I'm not certain that 'read zero bytes from this address' is a valid call, although there's no specific test for it. Are you using i2cMasterReceiveTimeout()?
On the slave, IIRC it should always respond with data - the source depends on the call type. The slave has no knowledge of how much data has been requested; it just keeps sending until a STOP is received. So I suspect the problem is at the master end.
It's a while since I tested all modes of the driver, so its possible that something has become broken outside my normal use case. However nothing substantive has been changed.
I2C Slave mode support?
Moderators: RoccoMarco, lbednarz, utzig, tfAteba, barthess
Re: I2C Slave mode support?
Hi steved,
I do not think this issue comes from your updated code, but is part of the not-yet-handled use cases.
The master cannot do anything in this case: as clock stretching has been left activated by default, the slave leaves the clock at the low level so the master is no longer able to communicate with the slave anyway - at least until the timer times out on the slave and release the SCL line so the master gets a chance to initiate a STOP.
I do not think an I2C request requires to have at least one data byte, whatever the direction.
The master is not running ChibiOS in my current setup.
Thanks for your help, I still need to dig further into the code.
It would be really nice the "slave" modes get an official API in ChibiOS - I'm also thinking about SPI here
I do not think this issue comes from your updated code, but is part of the not-yet-handled use cases.
The master cannot do anything in this case: as clock stretching has been left activated by default, the slave leaves the clock at the low level so the master is no longer able to communicate with the slave anyway - at least until the timer times out on the slave and release the SCL line so the master gets a chance to initiate a STOP.
I do not think an I2C request requires to have at least one data byte, whatever the direction.
The master is not running ChibiOS in my current setup.
Thanks for your help, I still need to dig further into the code.
It would be really nice the "slave" modes get an official API in ChibiOS - I'm also thinking about SPI here
- Professor Tarantoga
- Posts: 3
- Joined: Thu Aug 20, 2020 1:30 pm
Re: I2C Slave mode support?
Hi folks.
I am really happy, that there is code for i2c slave mode available (thanks for that), but i do have some little problem, getting it to work properly. Maybe someone can give me a hint?
I am using the NUCLEO-F767ZI, OS is 20.3.1 and code compiles without any error.
DMA disabled.
From the given examples i use following code to get slave mode up:
i2cStart(&slaveI2cPort, &slaveI2Cconfig);
slaveI2cPort.slaveTimeout = TIME_MS2I(500);
initialReply.size = strlen((char *)initialReply.body) + 1;
i2cSlaveConfigure(&slaveI2cPort, &echoRx, &initialReply);
In i2cSlaveConfigure function i2c_lld_slaveReceive is called and i2cStartReceive should be called in order to activate rx interrupt (I2C_CR1_RXIE). But i2cp->mode is set to idle and because of if (i2cp->mode == i2cLockedRxing && rxMsg->body && rxMsg->size) function i2cStartReceive is never called.
Am I missing something?
Thanks in advance
I am really happy, that there is code for i2c slave mode available (thanks for that), but i do have some little problem, getting it to work properly. Maybe someone can give me a hint?
I am using the NUCLEO-F767ZI, OS is 20.3.1 and code compiles without any error.
DMA disabled.
From the given examples i use following code to get slave mode up:
i2cStart(&slaveI2cPort, &slaveI2Cconfig);
slaveI2cPort.slaveTimeout = TIME_MS2I(500);
initialReply.size = strlen((char *)initialReply.body) + 1;
i2cSlaveConfigure(&slaveI2cPort, &echoRx, &initialReply);
In i2cSlaveConfigure function i2c_lld_slaveReceive is called and i2cStartReceive should be called in order to activate rx interrupt (I2C_CR1_RXIE). But i2cp->mode is set to idle and because of if (i2cp->mode == i2cLockedRxing && rxMsg->body && rxMsg->size) function i2cStartReceive is never called.
Am I missing something?
Thanks in advance
Re: I2C Slave mode support?
Long time since I looked at the code in detail, but I think you'll find that i2cStartReceive() is called (maybe via a convoluted route) once the device has received a correct I2C address.
Looking at my code, I have this sequence:
You don't mention calling i2cMatchAddress(), so that could be the problem.
Note: I always regard I2C addresses as 8 bits, with bit 0 always zero; Chibi uses a 7-bit value.
If you look back in this thread, there should be some pointers to the test harnesses I used originally when making the code work. (I do have this feeling that the I2Cv2 code might be over-complicated, but have never had time to revisit it)
Looking at my code, I have this sequence:
Code: Select all
#if HAL_USE_I2C_SLAVE
slaveI2cPort.slaveTimeout = MS2ST(100); // Time for complete message
#endif
i2cMatchAddress(&slaveI2cPort, slaveI2Caddress/2);
i2cSlaveConfigure(&slaveI2cPort, &echoRx, &initialReply);
You don't mention calling i2cMatchAddress(), so that could be the problem.
Note: I always regard I2C addresses as 8 bits, with bit 0 always zero; Chibi uses a 7-bit value.
If you look back in this thread, there should be some pointers to the test harnesses I used originally when making the code work. (I do have this feeling that the I2Cv2 code might be over-complicated, but have never had time to revisit it)
- Professor Tarantoga
- Posts: 3
- Joined: Thu Aug 20, 2020 1:30 pm
Re: I2C Slave mode support?
Hej steved,
thanks for answering.
Indeed I overlooked i2cMatchAddress(). Beside that I was struggeling with some inconveniences in my test setup. Meanwhile I managed to get something working.
As I don't have any experience with DMA, I disabled DMA. i2c should now run in interrupt mode.
I can see the received data in the provided rx-buffer but data is not further handled in any way.
i2cp->slaveBytes is always 0
I found a function i2cEndSlaveRxDMA, but no end-function for interrupt driven mode.
Could it be that your code is only working with DMA?
I will try DMA-mode and see, although it would be nice if you can give me a short feedback on interrupt driven mode.
Thanks and best regards
PT
thanks for answering.
Indeed I overlooked i2cMatchAddress(). Beside that I was struggeling with some inconveniences in my test setup. Meanwhile I managed to get something working.
As I don't have any experience with DMA, I disabled DMA. i2c should now run in interrupt mode.
I can see the received data in the provided rx-buffer but data is not further handled in any way.
i2cp->slaveBytes is always 0
I found a function i2cEndSlaveRxDMA, but no end-function for interrupt driven mode.
Could it be that your code is only working with DMA?
I will try DMA-mode and see, although it would be nice if you can give me a short feedback on interrupt driven mode.
Thanks and best regards
PT
Re: I2C Slave mode support?
Does look as if my 'real' code was using the I2C in DMA driven mode, although the driver was tested with both DMA and interrupts for a range of message sizes up to 563 bytes.
My applications send a message to the device, and always expect a reply.
Last thing I do in initialisation is:
The key data block is:
Then the key parts of my message processor are:
Hope that helps
My applications send a message to the device, and always expect a reply.
Last thing I do in initialisation is:
Code: Select all
i2cSlaveConfigure(&slaveI2cPort, &echoRx, &initialReply);
The key data block is:
Code: Select all
const I2CSlaveMsg echoRx =
{
sizeof(rxBody), /* max sizeof received msg body */
rxBody, /* body of received msg */
NULL, /* do nothing on address match */
messageProcessor, /* Routine to process received messages */
catchError /* Error hook */
};
Then the key parts of my message processor are:
Code: Select all
void messageProcessor(I2CDriver *i2cp)
{
size_t len = i2cSlaveBytes(i2cp); // Number of bytes received
if (len >= sizeof(rxBody))
len = sizeof(rxBody)-1;
rxBody[len]=0;
/* Process received message, generate response */
uint8_t rxLen = checkRxMessage(rxBody);
if (rxLen == 0)
{
strcpy((char *)txBody, errorReplyBody);
echoReply.size = strlen(errorReplyBody);
}
else
{
uint8_t txLen = processMessage(&rxBody, rxLen, &txBody);
txBody[1 + txLen] = '\0'; // Null terminate for simplicity
echoReply.size = txLen;
}
i2cSlaveReplyI(i2cp, &echoReply);
}
Hope that helps
- Professor Tarantoga
- Posts: 3
- Joined: Thu Aug 20, 2020 1:30 pm
Re: I2C Slave mode support?
I am now running DMA-mode. The data is received correctly and put into the rx-buffer.
Unfortunately the messageProcessor is never called so I cannot handle the data.
debugging codes are: 0x82, 0x80, | : 0x04, 0x13, 0x14, 0x05 : |
I understand:
82&80 init transfer
04 address match
13 address match receive
14 receive
05 stop
But where is the data handled?
Maybe I am stuck on outdated code od still missing something?
Thanks
best regards
PT
Unfortunately the messageProcessor is never called so I cannot handle the data.
debugging codes are: 0x82, 0x80, | : 0x04, 0x13, 0x14, 0x05 : |
I understand:
82&80 init transfer
04 address match
13 address match receive
14 receive
05 stop
But where is the data handled?
Maybe I am stuck on outdated code od still missing something?
Thanks
best regards
PT
Re: I2C Slave mode support?
Professor Tarantoga wrote:But where is the data handled?
Maybe I am stuck on outdated code od still missing something?
PT
I've just started using I2C slave mode in a different way to previously, and found exactly the same as you. It's when the master just sends, without requiring a reply - as you say, the data isn't handled.
Did you ever fix the problem?
Re: I2C Slave mode support?
Well, this is how I fixed it for I2Cv2 - just update the LLD.
Works with and without DMA.
Code could still do with a serious tidy up, but at least it works.
Works with and without DMA.
Code could still do with a serious tidy up, but at least it works.
- Attachments
-
- I2Cv2.7z
- (16.35 KiB) Downloaded 231 times
Re: I2C Slave mode support?
Is there a working i2c-slave code for stm32f103? I'm trying many variants published in this topic, but no one working Please help me!
Who is online
Users browsing this forum: No registered users and 28 guests