I2C Slave mode support?

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: utzig, lbednarz, tfAteba, barthess, RoccoMarco

eblot
Posts: 18
Joined: Fri Dec 08, 2017 5:33 pm
Been thanked: 1 time

Re: I2C Slave mode support?

Postby eblot » Mon Dec 11, 2017 7:57 pm

steved wrote:Have you caught up with this thread? There's an example which might help pin down the problem.


I should say that I'm lost with which is the "good" I2CSlave implementation to pick.
I tried to select it by archive (ZIP) date.

With the current implementation (for I2CV2), on STM32L4, there might be an issue with the ISR flags:

It seems the receive completion trigger relies on bit I2C_ISR_TC, which is documented as "TC: TransferComplete (master mode)" in ST data sheet. The `i2cp->slaveRx->processMsg(i2cp)` is therefore never called since I2C_ISR_TC does not seem to updated in slave mode.

Adding this code snippet to the I2C_ISR_STOPF bit management "solves" (should I say "works around" :P) the problem I described, but I'm a newbie with the STM32L4, so it might not be the proper way to deal with this issue. Any piece of advice is very welcome!

I also have a couple of question: it seems that i2cp->state is always stuck to I2C_READY when working as I2C slave. If this assumption is correct, I think it might be worth to document it.

Thanks,
Manu

eblot
Posts: 18
Joined: Fri Dec 08, 2017 5:33 pm
Been thanked: 1 time

Re: I2C Slave mode support?

Postby eblot » Mon Dec 11, 2017 8:00 pm

Giovanni wrote:hi,
Unlikely shot term, problem is support not code.
Giovanni


I get it, no problem.

In this case, would it be possible to store these proposed changes in a DCVS repository [Git or other], with one or more dev branch(es) if the various developments cannot be easily reconciled, so that improvements and bug fix can be easily tracked?

steved
Posts: 770
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 10 times
Been thanked: 122 times

Re: I2C Slave mode support?

Postby steved » Tue Dec 12, 2017 10:35 am

These are the latest routines I'm using, with 17.6.3; don't think they've changed for a year or two. The V2 routines are being used on the 32F0 and 32F7 processors. I've not used I2C on the 'L' processors at all; AIUI the peripheral should be identical to other processors, but one never knows. I'm only using a 100kHz clock.

Perhaps worth mentioning that on the slave received messages are processed in an interrupt context, so the handler needs to be kept tight; I had to copy some messages into a holding area to be processed by another thread.
Attachments
Chibi_I2C_Slave_17.6.3.zip
(44.28 KiB) Downloaded 98 times

eblot
Posts: 18
Joined: Fri Dec 08, 2017 5:33 pm
Been thanked: 1 time

Re: I2C Slave mode support?

Postby eblot » Tue Dec 12, 2017 3:02 pm

steved wrote:These are the latest routines I'm using, with 17.6.3; don't think they've changed for a year or two. The V2 routines are being used on the 32F0 and 32F7 processors. I've not used I2C on the 'L' processors at all; AIUI the peripheral should be identical to other processors, but one never knows. I'm only using a 100kHz clock.


I'm using a 400 KHz clock.
I've replaced the I2C slave code with the one from your archive.

It seems to work fine in the master->slave direction. However in the opposite direction (slave->master), the logic analyser shows that sometimes, the first byte sent from the slave is not part of the output buffer, but the first byte of the last input buffer. It seems to be the same behaviour with and without DMA transfer... I even replaced the output buffer with const one (i.e. that should be stored in flash, therefore not modifiable, just to be sure it cannot be overwritten with a buffer overflow) and no DMA, and I still observe this weird output with the logic analyser :-(

I've added some trace using the qEvt() macro to check what's pushed into the TXDR register, and the alien byte never shows up... Weird, weird, weird.

steved wrote:Perhaps worth mentioning that on the slave received messages are processed in an interrupt context, so the handler needs to be kept tight; I had to copy some messages into a holding area to be processed by another thread.


My handling routines are actually very short:

Code: Select all

static void
_mx_handle_request(I2CDriver * i2cp)
{
   _mx_engine.me_address = _mx_engine.me_inbuf[0]>>8U;
   _mx_msg.mm_rsp_msg.body = (uint8_t *)&_mx_por_values[_mx_engine.me_address];
   _mx_msg.mm_rsp_msg.size =
      (MX_REGISTER_MAP_SIZE-_mx_engine.me_address)*sizeof(uint16_t);
}

static void
_mx_handle_response(I2CDriver * i2cp)
{
   _mx_engine.me_address = 0U;
   _mx_msg.mm_rsp_msg.body = NULL;
   _mx_msg.mm_rsp_msg.size = 0;
}

eblot
Posts: 18
Joined: Fri Dec 08, 2017 5:33 pm
Been thanked: 1 time

Re: I2C Slave mode support?

Postby eblot » Tue Dec 12, 2017 3:48 pm

eblot wrote:However in the opposite direction (slave->master), the logic analyser shows that sometimes, the first byte sent from the slave is not part of the output buffer, but the first byte of the last input buffer. It seems to be the same behaviour with and without DMA transfer...


Additional note: the expected count of bytes is sent, but as the first byte is replaced with an invalid one, the last byte of the expected sequence is NOT sent: the actual byte sequence appears to be shifted by one byte, as it looks like the I2C HW TXDR is not empty when the transmission starts.

I initially thought the invalid byte was the first byte of the previous reception byte sequence, but this makes no sense. However with my setup, it appears it is the same value as the last byte of previous request byte sequence, which makes more sense.

Forcing

Code: Select all

I2CD1.i2c->ISR = I2C_ISR_TXE; // other bits but TXIS are R/O

from the previous request completion routine seems to clear out this issue.

I'm really not sure it is the proper way to fix this. The actual cause of the issue (TXDR or the I2C shift register is not empty of master read request) is still unknown.

STM32L4x2 reference manual:

ST wrote:Bit0 TXE: Transmit data register empty (transmitters)
This bit is set by hardware when the I2C_TXDR register is empty. It is cleared when the next data to be sent is written in the I2C_TXDR register.
This bit can be written to ‘1’ by software in order to flush the transmit data register I2C_TXDR. Note: This bit is set by hardware when PE=0.


I wonder if anyone has already tested this driver with a repeated start condition? Could some extra care be needed in this case?

Sequence:

Code: Select all

START | WRITE ADDR | WRITE BYTE | REPEATED START | READ ADDR | READ BYTE1 ... READ BYTE | STOP

eblot
Posts: 18
Joined: Fri Dec 08, 2017 5:33 pm
Been thanked: 1 time

Re: I2C Slave mode support?

Postby eblot » Tue Dec 12, 2017 7:28 pm

eblot wrote:In this case, would it be possible to store these proposed changes in a DCVS repository [Git or other], with one or more dev branch(es) if the various developments cannot be easily reconciled, so that improvements and bug fix can be easily tracked?

https://github.com/ChibiOS/ChibiOS :-)

steved
Posts: 770
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 10 times
Been thanked: 122 times

Re: I2C Slave mode support?

Postby steved » Tue Dec 12, 2017 9:41 pm

eblot wrote:I wonder if anyone has already tested this driver with a repeated start condition? Could some extra care be needed in this case?

Sequence:

Code: Select all

START | WRITE ADDR | WRITE BYTE | REPEATED START | READ ADDR | READ BYTE1 ... READ BYTE | STOP

Its quite a while since I've needed to look at the hardware level of the I2C bus. However I can say that in master mode I've not had any problem talking to devices other than another ST chip - certainly FRAM, TOD clock (DS1340 or similar) and the DS2483, and maybe others. So I would assume that a repeated start is being produced, and I've not found any need for extra care in this situation.

In slave mode, I've only ever talked to another ST device, and in any case wouldn't expect to produce a repeated start when the slave is responding.

User avatar
alex31
Posts: 334
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 33 times
Been thanked: 46 times
Contact:

Re: I2C Slave mode support?

Postby alex31 » Mon Jan 08, 2018 2:24 pm

steved say :
Attachments

Chibi_I2C_Slave_17.6.3.zip
(44.28 KiB) Downloaded 7 times



In this i2cSlave distribution (the more up2date ?)
I have been hit by a bug (I2CV1), using i2cstop (after an i2cstart) trigger an SV#6 in wakeup_isr, apparently, the function is called in a non isr context.

Alexandre

User avatar
alex31
Posts: 334
Joined: Fri May 25, 2012 10:23 am
Location: toulouse, france
Has thanked: 33 times
Been thanked: 46 times
Contact:

Re: I2C Slave mode support?

Postby alex31 » Tue Jan 09, 2018 11:18 am

Another bug with this i2c implementation (Chibi_I2C_Slave_17.6.3.zip) is incorrect status return value when function call fail :

i2cMasterTransmitTimeout return positive value in case of error instead -1 (MSG_RESET) or -2 (MSG_TIMEOUT)

Alexandre

steved
Posts: 770
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 10 times
Been thanked: 122 times

Re: I2C Slave mode support?

Postby steved » Tue Jan 09, 2018 2:18 pm

alex31 wrote:steved say :
Attachments

Chibi_I2C_Slave_17.6.3.zip
(44.28 KiB) Downloaded 7 times



In this i2cSlave distribution (the more up2date ?)
I have been hit by a bug (I2CV1), using i2cstop (after an i2cstart) trigger an SV#6 in wakeup_isr, apparently, the function is called in a non isr context.

Alexandre

It's the latest version I'm using (although I've mostly moved away from I2Cv1). I can see the path - don't see any need to call reporterrors() from i2cstop(), so you could just create an alternative version of wakeup_isr() which can be directly called from i2cstop()


Return to “General Support”

Who is online

Users browsing this forum: No registered users and 5 guests