Page 2 of 3
Re: I2C err
Posted: Sat Sep 08, 2018 3:47 pm
by steved
BreederBai wrote:Giovanni wrote:Are I2C pins programmed in the right way? do you have external pull up resistors? there are several possible causes for the I2C to hang, how you call that function is not very important.
Giovanni
Hello, I am using PB6, 7 pins, configured as ‘Alternate Open Drain output 2MHz’ Mode, initial level is high.
Code: Select all
#define VAL_GPIOBCRL 0xEE222888
#define VAL_GPIOBCRH 0x88488A48
#define VAL_GPIOBODR ((1 << 6) | (1 << 7))
The submission number of the ChibiOS I am using is 7d187a140e64db297eb5ef788f0f5dc0dd0d3fde, November 21, 2016 4:52 PM.
I have an external pull-up resistor and the pull-up resistor is 1K.
This make it look as if you are manually writing to the CPIO registers, rather than using Chibi's capabilities.
Have you configured the relevant alternate function number? (I've not used the 32F1XX family, but on the 32F4XX, which has the same I2C peripheral, its AF4).
It also looks as if you might be using a relatively old version of ChibiOs (although the I2C has worked fine for years).
You can generally set up the initial mode etc for I/O pins in the board configuration file; then you just need to do i2cstart().
Re: I2C err
Posted: Sat Sep 08, 2018 4:08 pm
by Giovanni
On F1 (GPIOv1) there are no alternate numbers, just alternate or not.
The driver is very old and proved to work, probably the problem is not where you are looking, I would bet on some HW issue (because bus locked).
Giovanni
Re: I2C err
Posted: Sun Sep 09, 2018 6:18 am
by BreederBai
Giovanni wrote:On F1 (GPIOv1) there are no alternate numbers, just alternate or not.
The driver is very old and proved to work, probably the problem is not where you are looking, I would bet on some HW issue (because bus locked).
Giovanni
I also suspect the reason for the hardware configuration.This is the code for my print debug information.
Code: Select all
os::lowsyslog("read in\n");
i2cAcquireBus(&I2C);
os::lowsyslog("read out,%d\n",int(i2cMasterTransmitTimeout(&I2C,
HAL_COMPASS_IST8310_I2C_ADDR,
tx_buf.data(),
tx_buf.size(),
rx_buf.data(),
rx_buf.size(),
10)));//TIME_INFINITE
i2cReleaseBus(&I2C);
This is the debug information printed.
Code: Select all
Bootloader struct values: CAN bitrate: 1000000, UAVCAN Node ID: 125
UniqueID :38FFD9054747353644301643
re
PANIC [mag_ist8310] i2c_lld_master_transmit_timeout
Core registers:
CONTROL 2
IPSR 0
APSR 60000000
xPSR 60000000
PRIMASK 1
BASEPRI 20
FAULTMASK 0
Process stack:
Pointer 20003328
R0 2
R1 30325555
R2 35353233
R3 1003333
R12 8030e90
R14[LR] 40005400
R15[PC] 0
PSR a
Main stack:
Pointer 20000900
R0 55555555
R1 55555555
R2 55555555
R3 55555555
R12 55555555
R14[LR] 55555555
R15[PC] 55555555
PSR 55555555
SCB:
AIRCR fa050300
SCR 0
CCR 0
SHCSR 0
CFSR 0
HFSR 0
DFSR 0
MMFAR e000ed34
BFAR e000ed38
AFSR 0
By debugging the code and debugging information, it can be seen that the debugging information is not printed and the operating system is restarted. It should be that the I2C read/write program triggered a hardware error.I am talking to you through Google Translate, I hope you can understand my reply.
Re: I2C err
Posted: Sun Sep 09, 2018 8:28 am
by steved
Check that you have sufficient stack allocated to the task that reads the I2c.
(If you use ChibiStudio, in includes a plugin that can show you stack usage)
Re: I2C err
Posted: Mon Sep 10, 2018 7:33 am
by Polux
From the message "i2c_lld_master_transmit_timeout" you could find the possible cause in the source code.
My guess is your peripheral is not correctly receiving, and it is not answering the read/write request => timout.
The peripheral address could be also wrong. Check if the address is not depending of some CS line on the chip. I had an issue with MS5611 (barometric pressure sensor), the address LSB is connected to a pin. On all flight controllers, this pin is connected to Vcc, but on mine it is connected to Gnd. Obviously, I had to change the address in the ArduPilot config, after searching for hours what was wrong

.
Angelo
Re: I2C err
Posted: Tue Sep 11, 2018 2:05 am
by BreederBai
Polux wrote:From the message "i2c_lld_master_transmit_timeout" you could find the possible cause in the source code.
My guess is your peripheral is not correctly receiving, and it is not answering the read/write request => timout.
The peripheral address could be also wrong. Check if the address is not depending of some CS line on the chip. I had an issue with MS5611 (barometric pressure sensor), the address LSB is connected to a pin. On all flight controllers, this pin is connected to Vcc, but on mine it is connected to Gnd. Obviously, I had to change the address in the ArduPilot config, after searching for hours what was wrong

.
Angelo
"i2c_lld_master_transmit_timeout" is a function.I guess the error was triggered while executing this function. Because the operating system does not restart when the I2C read/write function is not called.
Re: I2C err
Posted: Tue Sep 11, 2018 2:27 am
by BreederBai
steved wrote:Check that you have sufficient stack allocated to the task that reads the I2c.
(If you use ChibiStudio, in includes a plugin that can show you stack usage)
I am using ”make“ compiled ChibiOS, may I ask how to increase the I2C stack in this case
Re: I2C err
Posted: Tue Sep 11, 2018 8:12 am
by steved
BreederBai wrote:steved wrote:Check that you have sufficient stack allocated to the task that reads the I2c.
(If you use ChibiStudio, in includes a plugin that can show you stack usage)
I am using ”make“ compiled ChibiOS, may I ask how to increase the I2C stack in this case
Updating the stack size is nothing to do with the development environment.
There isn't a specific stack for I2C; you need to ensure that there is sufficient stack space assigned to the thread(s) which call I2C routines.
For the main thread, this is done in the main make file (USE_PROCESS_STACKSIZE). For other threads, its specified when you create the thread.
Re: I2C err
Posted: Mon Sep 17, 2018 7:14 am
by BreederBai
I found a strange phenomenon,When I commented the code like this.Calling the i2cMasterTransmitTimeout function will still restart.
Code: Select all
msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
const uint8_t *txbuf, size_t txbytes,
uint8_t *rxbuf, size_t rxbytes,
systime_t timeout) {
I2C_TypeDef *dp = i2cp->i2c;
systime_t start, end;
#if defined(STM32F1XX_I2C)
// osalDbgCheck((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL)));
#endif
/* Resetting error flags for this transfer.*/
// i2cp->errors = I2C_NO_ERROR;
/* Initializes driver fields, LSB = 0 -> transmit.*/
// i2cp->addr = (addr << 1);
/* Releases the lock from high level driver.*/
//osalSysUnlock();
/* TX DMA setup.*/
// dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
// dmaStreamSetMemory0(i2cp->dmatx, txbuf);
// dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
/* RX DMA setup.*/
// dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
// dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
// dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
/* Calculating the time window for the timeout on the busy bus condition.*/
// start = osalOsGetSystemTimeX();
// end = start + OSAL_MS2ST(STM32_I2C_BUSY_TIMEOUT);
/* Waits until BUSY flag is reset or, alternatively, for a timeout
condition.*/
// while (true) {
osalSysLock();
/* If the bus is not busy then the operation can continue, note, the
loop is exited in the locked state.*/
// if (!(dp->SR2 & I2C_SR2_BUSY) && !(dp->CR1 & I2C_CR1_STOP))
// break;
/* If the system time went outside the allowed window then a timeout
condition is returned.*/
// if (!osalOsIsTimeWithinX(osalOsGetSystemTimeX(), start, end))
// return MSG_TIMEOUT;
osalSysUnlock();
// }
/* Starts the operation.*/
//dp->CR2 |= I2C_CR2_ITEVTEN;
//dp->CR1 |= I2C_CR1_START;
/* Waits for the operation completion or a timeout.*/
//return osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
return true;
}
But after I commented out osalSysLock() and osalSysUnlock(), the system will not restart repeatedly.But when I further commented and modified the code, the system started to restart again and again.
Code: Select all
msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
const uint8_t *txbuf, size_t txbytes,
uint8_t *rxbuf, size_t rxbytes,
systime_t timeout) {
I2C_TypeDef *dp = i2cp->i2c;
systime_t start, end;
#if defined(STM32F1XX_I2C)
// osalDbgCheck((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL)));
#endif
/* Resetting error flags for this transfer.*/
// i2cp->errors = I2C_NO_ERROR;
/* Initializes driver fields, LSB = 0 -> transmit.*/
// i2cp->addr = (addr << 1);
/* Releases the lock from high level driver.*/
//osalSysUnlock();
/* TX DMA setup.*/
// dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
// dmaStreamSetMemory0(i2cp->dmatx, txbuf);
// dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
/* RX DMA setup.*/
// dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
// dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
// dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
/* Calculating the time window for the timeout on the busy bus condition.*/
// start = osalOsGetSystemTimeX();
// end = start + OSAL_MS2ST(STM32_I2C_BUSY_TIMEOUT);
/* Waits until BUSY flag is reset or, alternatively, for a timeout
condition.*/
// while (true) {
//osalSysLock();
/* If the bus is not busy then the operation can continue, note, the
loop is exited in the locked state.*/
// if (!(dp->SR2 & I2C_SR2_BUSY) && !(dp->CR1 & I2C_CR1_STOP))
// break;
/* If the system time went outside the allowed window then a timeout
condition is returned.*/
// if (!osalOsIsTimeWithinX(osalOsGetSystemTimeX(), start, end))
// return MSG_TIMEOUT;
//osalSysUnlock();
// }
/* Starts the operation.*/
//dp->CR2 |= I2C_CR2_ITEVTEN;
//dp->CR1 |= I2C_CR1_START;
/* Waits for the operation completion or a timeout.*/
return osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
//return true;
}
Re: I2C err
Posted: Tue Sep 18, 2018 3:09 am
by BreederBai
Giovanni wrote:On F1 (GPIOv1) there are no alternate numbers, just alternate or not.
The driver is very old and proved to work, probably the problem is not where you are looking, I would bet on some HW issue (because bus locked).
Giovanni
After debugging, I found that the system restarts should be related to this broken code.
Code: Select all
msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
const uint8_t *txbuf, size_t txbytes,
uint8_t *rxbuf, size_t rxbytes,
systime_t timeout) {
I2C_TypeDef *dp = i2cp->i2c;
systime_t start, end;
#if defined(STM32F1XX_I2C)
osalDbgCheck((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL)));
#endif
/* Resetting error flags for this transfer.*/
i2cp->errors = I2C_NO_ERROR;
/* Initializes driver fields, LSB = 0 -> transmit.*/
i2cp->addr = (addr << 1);
/* Releases the lock from high level driver.*/
osalSysUnlock();
In this line, if read a byte, an error will be reported. The system will be stuck in an infinite loop until the watchdog times out and the system restarts.
Code: Select all
osalDbgCheck((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL)));