I2C Slave Mode
Re: I2C Slave Mode
Postby rudi » Thu Oct 27, 2016 1:22 am
dkaufmann wrote:Hi Rudi,
okay I see. thanks for this one. Gonna try it out.
best regards
D.
one hint i get perhabs for you important too

- CCOUNT SR it's 32 bits
- overflow of CCOUNT detectable? -- no, there's nothing that can tell you about an overflow. No interrupt, no overflow bit.
- is there an interrupt for CCOUNT? Yes, there is a number of CCOMPARE SRs. You can write a value there and then an IRQ will be raised once CCOUNT reaches that value.
For more details please see xtensa ISA book (e.g. http://0x04.net/~mwk/doc/xtensa.pdf ), 4.4.6 Timer interrupt option.
have phun
best wishes
rudi

-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
- martinayotte
- Posts: 10
- Joined: Tue Nov 04, 2014 4:33 am
Re: I2C Slave Mode
Postby martinayotte » Fri Oct 28, 2016 12:21 am
rudi wrote:martinayotte wrote:Rudi, did you got chance to upload your I2CSlave code somewhere ?
edit:
the missunderstand was cleaned now.
lets see what happens.
rudi
I don't understand your above comment ...
My question was : do you have any github where we can look at your ESP8266 I2C Slave code ?
Re: I2C Slave Mode
Postby rudi » Fri Oct 28, 2016 12:58 am
martinayotte wrote:rudi wrote:martinayotte wrote:Rudi, did you got chance to upload your I2CSlave code somewhere ?
edit:
the missunderstand was cleaned now.
lets see what happens.
rudi
I don't understand your above comment ...
My question was : do you have any github where we can look at your ESP8266 I2C Slave code ?

this was other theme - i have wait for the devkitc from john and want make a esp family i2c example,
but had not get .. this theme is cleared - not to do with you, martin, sry for the
confusion.
need we the github code any more?
we have here opendrain setup, ack , start, stop, isr and other as example.
best wishes
rudi

-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
- martinayotte
- Posts: 10
- Joined: Tue Nov 04, 2014 4:33 am
Re: I2C Slave Mode
Postby martinayotte » Fri Oct 28, 2016 10:05 pm
Re: I2C Slave Mode
Postby rudi » Fri Oct 28, 2016 10:24 pm
martinayotte wrote:@Rudi, Few weeks ago, you were saying that you will share this I2C Slave code, and said that it should be after Chinese holiday ...
edit:
yes i did this say.
read the code here - this is my share -
but me was say too, that i get devKitC,
but i have not get. so my thinked demo project i can not build.
this would be a gift on second birthday to bbs
i had pm you the things what happens, but you have not read more weeks.
at just in time - i get no devkitc from adafruit, olimex or espressif.
so - i cant build my thinked demo with all espressif boards
and i do not start again theme in esp8266 that was done in last year.. sry
and btw:
here now a part of detailed things in the thread that you not read on technicals docu.
- pin setup
- opendrain
- isr theme
- start, stop, addr, data
where is the problem now to build an own project with this as base?
if there is no understand for the code here,
there cant be an understand of the demo project too,
so please.
copy & paste is not good for teach.
so my steps are teached bit by bit with each instruction to do INTR on SDA, SCL
in v 0.1 for Start, Stop, Read cmd , Write cmd, SDA, SCL, Addr Match, ISR
your steps now: Data ( its the same principal ) and a idea what you do with I2C.
example send cmd by I2C Master to I2C Slave for AT Commands based on I2C.
i do nobody hims homework.
nobody pay me the time or gives me DevKitC to do the things...
and i am not work at espressif - i am customer like you.
sry
i do not more coment this theme here martin.
there stands all info to create a own I2C Slave.c and Header and demo project.
rudi
-------------------------------------
love it, change it or leave it.
-------------------------------------
問候飛出去的朋友遍全球魯迪
- martinayotte
- Posts: 10
- Joined: Tue Nov 04, 2014 4:33 am
Re: I2C Slave Mode
Postby martinayotte » Tue Nov 01, 2016 1:58 am
You've said that you will share your code, but had never shared it.
Now, you are saying "i do nobody hims homework" ...

With such attitude, probably yourself won't get any help from other when you will need it ...
Re: I2C Slave Mode
Postby davydnorris » Thu Nov 03, 2016 4:58 pm
martinayotte wrote:I don't understand, I see an email from you on Oct 19, but it has been flag "deleted by you", so I can't read it.
You've said that you will share your code, but had never shared it.
Now, you are saying "i do nobody hims homework" ...
With such attitude, probably yourself won't get any help from other when you will need it ...
I have to say Martin, I don't think rudi will ever need much help from others - he is a legend, and a prolific poster here and in the other ESP forums. He has my respect big time!!
I took the info here and was able to get code running pretty quickly - I don't think there's anything missing from the explanations that I have found so far.
Big thanks rudi!!
- martinayotte
- Posts: 10
- Joined: Tue Nov 04, 2014 4:33 am
Re: I2C Slave Mode
Postby martinayotte » Sat Nov 05, 2016 5:06 am
Re: I2C Slave Mode
Postby dkaufmann » Mon Nov 21, 2016 4:47 pm
I also shared some code here about the I2C slave code. But I still have some troubles with interrupt latencies. Sometimes I detect wrong START messages because the delay of measuring the inputs is too bad. Any ideas how to avoid this problem? By the way, I measure the inputs right at the beginning of the ISR.
any help is appreciated. here is my code of the ISR:
Code: Select all
// ---------------- Interrupt Service Routine ISR -----------
void gpio_intrHandlerCB (void)
{
// variables
uint8 temp_SDA = GPIO_INPUT_GET(I2C_SDA_PIN);
uint8 temp_SCK = GPIO_INPUT_GET(I2C_SCK_PIN);
i2c_state_t i2c_state = REC_ADDR;
uint8 bit_cntr = 0; // counts clock edges to read data
uint8 byte_cntr = 0; // counts databytes
uint8 i2c_address = 0; // 8 Bit without R/W
uint8 i2c_rec_data = 0; // 8 Bit receive data
uint8 i2c_rwn = 0; // 0: write, 1: read
uint8 i2c_stop = 0; // stop signal
uint16 i2c_TO_cntr = 0;
// read GPIO status register to check which line had an interrupt
uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
// handle SDA Pin Interrupt
//-----------------------------------------------------------------------
if ( (gpio_status & BIT(I2C_SDA_PIN)) && (temp_SCK)) // if SCL = high : START
{
//GPIO_OUTPUT_SET(DEBUG_PIN4, 1);
//GPIO_OUTPUT_SET(DEBUG_PIN4, 0);
// disable interrupt on SDA pin only when START or STOP received
gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SDA_PIN), GPIO_PIN_INTR_DISABLE);
if (temp_SDA) // if SDA rising: STOP
{
i2c_stop = 1;
//enable START interrupt again
gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SDA_PIN), GPIO_PIN_INTR_ANYEDGE);
}
else // START
{
while (!i2c_stop)
{
switch (i2c_state)
{
case REC_ADDR:
//on next pos edge on SCL: read addr
for (bit_cntr = 0; bit_cntr<7; bit_cntr++)
{
// read 7 bit address
// wait for falling edge
i2c_TO_cntr = 0;
while (GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
// wait for rising edge
i2c_TO_cntr = 0;
while (!GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
i2c_address |= (((uint8) (GPIO_INPUT_GET(I2C_SDA_PIN))) << (6-bit_cntr));
}
if (i2c_address == I2C_SLAVEADDR)
{
i2c_state = READ_RW;
}
else
{
i2c_state = REC_ADDR; // init start state
i2c_stop = 1; // leave ISR
//enable START interrupt again
gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SDA_PIN), GPIO_PIN_INTR_ANYEDGE);
};
break;
case READ_RW: // read the rwn bit (0 = MASTER write, 1 = MASTER read)
// wait for falling edge
i2c_TO_cntr = 0;
while (GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
// wait for rising edge
i2c_TO_cntr = 0;
while (!GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
i2c_rwn = GPIO_INPUT_GET(I2C_SDA_PIN); // read databit
byte_cntr=0; // reset databyte counter
i2c_state = SEND_ACK;
break;
case SEND_ACK:
// wait for falling edge
i2c_TO_cntr = 0;
while (GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
GPIO_OUTPUT_SET(I2C_SDA_PIN, 0); // ACK = SDA low
GPIO_OUTPUT_SET(I2C_INT_PIN, 1); // release interrupt line after receiving correct address
if (i2c_rwn) // SEND_DATA?
{
i2c_state = SEND_DATA; // = MASTER READ DATA
}
else // Receive data
{
i2c_state = REC_DATA; // = MASTER WRITE DATA
}
break;
case SEND_DATA: // C5
// Slave sends Data to master: MSB first
for (bit_cntr = 0; bit_cntr < 8; bit_cntr++)
{
// wait for rising edge
i2c_TO_cntr = 0;
while (!GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
// wait for falling edge
i2c_TO_cntr = 0;
while (GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
// write data on falling edge
GPIO_OUTPUT_SET(I2C_SDA_PIN, (i2c_TxBuf[byte_cntr]&(0x80 >> bit_cntr)?1:0)); // shift out data: if true = 1 else = 0
}
// check ACK
// wait for rising edge
i2c_TO_cntr = 0;
while (!GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
// wait for falling edge
i2c_TO_cntr = 0;
while (GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
GPIO_OUTPUT_SET(I2C_SDA_PIN,1); // release SDA Pin
// wait for rising edge
i2c_TO_cntr = 0;
while (!GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
if (!GPIO_INPUT_GET(I2C_SDA_PIN)) // ACK:
{
byte_cntr++;
}
else // NACK: END SEND DATA
{
byte_cntr=0; // reset byte counter
i2c_stop = 1;
//enable START interrupt again to read master's answer
gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SDA_PIN), GPIO_PIN_INTR_ANYEDGE);
};
break;
case REC_DATA: // C4 -> MASTER WRITE
//Slave reads 8 databit from master
// wait for rising edge
i2c_TO_cntr = 0;
while (!GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
for (bit_cntr = 0; bit_cntr < 8; bit_cntr++)
{
temp_SDA = GPIO_INPUT_GET(I2C_SDA_PIN);
i2c_TO_cntr = 0;
while (GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) // wait for falling edge (end ack read)
{
i2c_TO_cntr++; // increase time out counter
os_delay_us(1);
// during high: check if data did not change -> STOP
if (temp_SDA != GPIO_INPUT_GET(I2C_SDA_PIN)){
i2c_stop = 1;
i2c_RxCount = byte_cntr+1;
i2c_rec_done = 1;
break;
}
}
if (i2c_stop) // if STOP occured, leave loop
break;
// release SDA pin on falling SCL edge:
GPIO_OUTPUT_SET(I2C_SDA_PIN, 1); // release I2C_SDA_PIN
// wait for rising edge
i2c_TO_cntr = 0;
while (!GPIO_INPUT_GET(I2C_SCK_PIN) || i2c_TO_cntr >= I2C_TIMEOUT) {
i2c_TO_cntr++;
os_delay_us(1);
}
i2c_rec_data |= (((uint8) (GPIO_INPUT_GET(I2C_SDA_PIN))) << (7-bit_cntr));
}
i2c_RxBuf[byte_cntr]=i2c_rec_data; // store received databyte
byte_cntr++; // increase databyte counter
i2c_rec_data = 0; // reset received databyte
i2c_state = SEND_ACK;
break;
default:
i2c_state = REC_ADDR;
} // end switch
} // end while
// state machine end: stop occured:
i2c_stop = 0; // reset stop flag
i2c_state = REC_ADDR; // init state
i2c_rec_data = 0;
i2c_address = 0;
};
//clear interrupt status for GPIOx (SDA)
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(I2C_SDA_PIN));
}
Who is online
Users browsing this forum: No registered users and 1 guest
Login
Newbies Start Here
Are you new to ESP8266?
Unsure what to do?
Dunno where to start?
Start right here!
Latest SDK
Documentation
Complete listing of the official ESP8266 related documentation release by ESPRESSIF!
Must read here!
- All times are UTC+08:00
- Top
- Delete all board cookies
About Us
Espressif Systems is a fabless semiconductor company providing cutting-edge low power WiFi SoCs and wireless solutions for wireless communications and Internet of Things applications. We are the manufacturer of ESP8266EX.