ESP8266 Developer Zone The Official ESP8266 Forum 2020-10-09T14:25:53+08:00 https://bbs.espressif.com:443/feed.php?f=49 2020-10-09T14:25:53+08:00 2020-10-09T14:25:53+08:00 https://bbs.espressif.com:443/viewtopic.php?t=65919&p=89999#p89999 <![CDATA[Documentation Request • Re: [ESP8266] TX power using certification tool]]> https://www.espressif.com/en/support/do ... ther-tools. It should able to pass the CE certification.

If unfortunately not, submit an issue on the website. https://www.espressif.com/en/contact-us ... -inquiries

Statistics: Posted by Her Mary — Fri Oct 09, 2020 2:25 pm


]]>
2020-10-02T21:31:39+08:00 2020-10-02T21:31:39+08:00 https://bbs.espressif.com:443/viewtopic.php?t=65919&p=89593#p89593 <![CDATA[Documentation Request • [ESP8266] TX power using certification tool]]>
Days ago, I have written a topic about the actual TX power when using certification tool provided from Espressif. For some unknown reasons, I could not find it anywhere in this forums (maybe, delay in approval process, or I posted in wrong place). So, I will repost my question here.

We are doing CE Certification verification in our lab. We are using a tool, which is based completely on your tool (https://bbs.espressif.com/viewtopic.php ... 341&p=4459), and issuing command wifitxout <Parameter1> <Parameter2> <Parameter3> to set the TX power. Here are some questions that we hope you can support:
- What is actual TX power if we set wifitxout 1 0 x, with x = -40, 216, -30, 226, -20, 236, 0. Do you have any document relating to this?
- Is this correct if we assuming that the parameter 1 and 2 also affects the actual TX power? If so, is there any document/test result containing the TX power with all cases of param 1, 2 and 3?

I'm looking forward to hear from you soon.

Best Regards,
Tan

Statistics: Posted by tannguyen_205 — Fri Oct 02, 2020 9:31 pm


]]>
2019-10-08T14:38:50+08:00 2019-10-08T14:38:50+08:00 https://bbs.espressif.com:443/viewtopic.php?t=25411&p=66437#p66437 <![CDATA[Documentation Request • Re: Packet-only mode]]> sniffer mode
function: wifi_send_pkt_freedom
ESP-NOW
?

Statistics: Posted by Guest — Tue Oct 08, 2019 2:38 pm


]]>
2019-01-08T15:03:32+08:00 2019-01-08T15:03:32+08:00 https://bbs.espressif.com:443/viewtopic.php?t=25411&p=36628#p36628 <![CDATA[Documentation Request • Packet-only mode]]>
Additional PHY register documentation or an example of how early testing on the ESP8089 was performed using mask ROM functions would be needed.


Here are our concessions:

We do not need or want the management stack, no AP mode, no client mode, no LWIP, timers, or well anything else. All we actually need is enough to wake the PHY up, tune to a channel, and receive + send.

We don't even need to use standard channel widths, The BBPLL can operate the peripheral bus at just about any speed, as our actual data transfer will be on the order of at most one packet every few seconds.

We do not need a sensitive receiver. We can sacrifice sensitivity of 20db or more without any issue. All communication will be performed at distances of ~10 meters line of sight or less.

We can use any encoding or rate, Any 802.11 or CDMA coding schemes are totally good to go.


Here is what we would need to do:

1) Operate without flash. We would need to be able to store the program on another microcontroller and bootload it into the UART at boot to run. This would limit our program space to IRAM only. I understand the mask rom is riddled with bugs, and that's why it's not used, but if all we need to do is wake up the PHY, surely this would be an option.

2) Need to reduce RX power. Is there ANY PHY setting that would reduce current draw by 20mA or more with the receiver running, even at a significant cost to sensitivity, or receive sgnal integrity?

Statistics: Posted by cnlohr — Tue Jan 08, 2019 3:03 pm


]]>
2018-12-19T21:49:12+08:00 2018-12-19T21:49:12+08:00 https://bbs.espressif.com:443/viewtopic.php?t=24925&p=36068#p36068 <![CDATA[Documentation Request • More specific document about system_rtc_clock_cali_proc() API, PLEASE?]]> I just need more info about this API. we need to know the exact bit representation for this API return value?

Regards.
IMAN.

Statistics: Posted by IMAN4K — Wed Dec 19, 2018 9:49 pm


]]>
2018-12-14T19:08:02+08:00 2018-12-14T19:08:02+08:00 https://bbs.espressif.com:443/viewtopic.php?t=874&p=36017#p36017 <![CDATA[Documentation Request • Re: 请在这里发表关于文档的需求]]> http://community.arubanetworks.com/t5/T ... a-p/257893

Statistics: Posted by Her Mary — Fri Dec 14, 2018 7:08 pm


]]>
2018-12-01T05:20:26+08:00 2018-12-01T05:20:26+08:00 https://bbs.espressif.com:443/viewtopic.php?t=874&p=35803#p35803 <![CDATA[Documentation Request • Re: 请在这里发表关于文档的需求]]> (1)能够给出关于 System_Event_t 详细文档?
(2)对于上述错误,如何处理?目前我是这样保存配置的,为什么无法解决这个问题?

Code:

   wifi_station_disconnect();
   system_restore();
   wifi_station_set_reconnect_policy(false);
   wifi_set_opmode_current(STATION_MODE);
   //wifi_station_get_config(sta_conf);
   os_memset(sta_conf->ssid, 0, 32);
   os_memset(sta_conf->password, 0, 64);
   os_strcpy(sta_conf->ssid, "some-ssid");
   os_strcpy(sta_conf->password, "some-password");
   sta_conf->bssid_set = 0;      //reset bssid_set
   wifi_station_set_config(sta_conf);
   wifi_station_set_config_current(sta_conf)
   

Statistics: Posted by rockywei — Sat Dec 01, 2018 5:20 am


]]>
2018-07-22T10:54:43+08:00 2018-07-22T10:54:43+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=22173#p22173 <![CDATA[Documentation Request • I2C Slave Mode]]>
Has anyone built code to use a a pic in i2c slave mode that they can share?

Thanks

Peter

Statistics: Posted by MelaniaZew — Sun Jul 22, 2018 10:54 am


]]>
2018-07-05T15:55:28+08:00 2018-07-05T15:55:28+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=20996#p20996 <![CDATA[Documentation Request • I2C Slave Mode]]> Statistics: Posted by RobertDot — Thu Jul 05, 2018 3:55 pm


]]>
2018-06-13T07:22:10+08:00 2018-06-13T07:22:10+08:00 https://bbs.espressif.com:443/viewtopic.php?t=4321&p=20711#p20711 <![CDATA[Documentation Request • Boot process / flash / rom]]>
can anyone describe the boot process - specifically the internal boot loader functionality. Does it just read 64K from SPI flash or is it more intelligent? I cant find the info in the L1 system spec.

Shareef.

Statistics: Posted by andreysnug — Wed Jun 13, 2018 7:22 am


]]>
2018-03-20T17:28:22+08:00 2018-03-20T17:28:22+08:00 https://bbs.espressif.com:443/viewtopic.php?t=9410&p=19697#p19697 <![CDATA[Documentation Request • ESP8285 flash details]]>
I would like to have some more informations on the 1MB embedded flash on the ESP8285, more than the 2 lines on the ESP8285 datasheet, like part number...

Regards

Statistics: Posted by adrien3d — Tue Mar 20, 2018 5:28 pm


]]>
2018-03-09T08:10:59+08:00 2018-03-09T08:10:59+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=19556#p19556 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
i already read the whole thread and i am on my way to write my own I2C Slave library, mine is interrupt driven,too. I can reach up to 100 kHz, but i want to reach Fast Mode (400 kHz). My biggest problem is, that my Interrupts get triggeres waaayy too slow. I am also reaching 2 µs (with 160 MHz CPU Speed) until i am able to write a GPIO, which is too slow to repsond fast enough and i would prefer running the ESP8266 at 80 MHz again.

So my question is: Is there meanwhile any faster way to run my ISR?

On Github i found the very intersting part from CNLohr, where he uses ASM instructions, but i am not able to understand and adopt these to my needs. I would basically like to use my current ISR and simply jump there from the ASM instructions, that runs as soon as the Interrupt flag is set.
https://github.com/cnlohr/espusb/blob/master/user/usb_asm_1bit.S

I hope my english is understandable, since i am from germany ;)

Statistics: Posted by Driftmonster — Fri Mar 09, 2018 8:10 am


]]>
2017-12-24T08:46:51+08:00 2017-12-24T08:46:51+08:00 https://bbs.espressif.com:443/viewtopic.php?t=832&p=18808#p18808 <![CDATA[Documentation Request • Re: Post Your Documentation Requirement Here]]> For an application I require to transfer continuously bulk of data between a cell phone and a device equipped with esp8266. I want to implement WIFI peer to peer(p2p) mode .would you introduce me some documentations which help me for implementing this mode of WIFI on esp8266.
thanks

Statistics: Posted by asd_60 — Sun Dec 24, 2017 8:46 am


]]>
2017-12-07T14:36:16+08:00 2017-12-07T14:36:16+08:00 https://bbs.espressif.com:443/viewtopic.php?t=8670&p=18588#p18588 <![CDATA[Documentation Request • gen_test_blank.py 脚本文件哪里可以获取到]]> gen_test_blank.py 脚本文件哪里可以获取到,在链接中文件中提到。如图。
>1)ESP 芯片平台 : ESP8266EX
>2)ESP SDK 版本号 :ESP8266_NONOS_SDK-2.1.0
>3)您参照的文档链接 : http://espressif.com/sites/default/file ... 1.6_en.pdf

Image

Statistics: Posted by binary — Thu Dec 07, 2017 2:36 pm


]]>
2017-10-15T22:23:40+08:00 2017-10-15T22:23:40+08:00 https://bbs.espressif.com:443/viewtopic.php?t=1761&p=16447#p16447 <![CDATA[Documentation Request • I2C with arduino]]> I have got a VS1033D breakout board from Sparkfun with me. I tried sending Mp3 data to the SDI.But it dint play the song . Please tell me how can i initialize the Decoder. Please describe in detail all the steps .
Also is it always necessary to tie the TEST pin to VDD ?

Statistics: Posted by Bentjudges — Sun Oct 15, 2017 10:23 pm


]]>
2017-09-12T13:49:43+08:00 2017-09-12T13:49:43+08:00 https://bbs.espressif.com:443/viewtopic.php?t=6004&p=15713#p15713 <![CDATA[Documentation Request • Re: AT instructions set should be reviewd]]>
So sorry for the inconvenience.

Those messages are logs for debugging. Only "OK" and "ERROR" should be used to check if the operation succeeded. Since ESP8266 AT has already been used by so many customers, we will not change the debugging messages. But for the new chipset ESP32, we will remove all unnecessary messages.

Thanks for your interest in ESP8266!

Statistics: Posted by ESP_Faye — Tue Sep 12, 2017 1:49 pm


]]>
2017-08-18T18:45:10+08:00 2017-08-18T18:45:10+08:00 https://bbs.espressif.com:443/viewtopic.php?t=6004&p=15217#p15217 <![CDATA[Documentation Request • AT instructions set should be reviewd]]>
The AT instruction set document should be reviewed and much better documented, focusing on the error messages. For example, documentation shows AT+CIPSTART commands returns "ERROR" or "ALREADY CONNECT", but in fact it returns 5/6 different messages some of them, and sometimes, used for several different non-related errors. Notice here and mixing the final error message with the "status"; for example "ALREADY CONNECT" is not the summary message (that is in fact "ERROR") but to show the kind of problem.

ALREADY CONNECT <= status or whatever you want to call it
ERROR <= summary

But in other cases we can get up to 2 responses for the same not documented, and so on up to 5-6 different messages none of them documented. And sometimes you get the problem description AFTER then "ERROR" string. Similar thing happens with other commands.

It looks trivial but it's not since you can get unexpected responses simply because you don't know they exist. I got some of these just testing one by one the AT commands whilst I was making a library to deal with them. Obviously forced me to increas the sofware complexity to patch these abundant non-regular cases.

Statistics: Posted by exerion — Fri Aug 18, 2017 6:45 pm


]]>
2017-05-24T03:58:24+08:00 2017-05-24T03:58:24+08:00 https://bbs.espressif.com:443/viewtopic.php?t=1409&p=13355#p13355 <![CDATA[Documentation Request • Re: Simple mesh example]]>
it would be really nice, if you could add some more detail to the explanation of the core-fuctions like espconn_mesh_establish and the different mesh-modes, though. I really appreciate the demo and it's really helpful, but some things won't become clear (please keep in mind, that we users don't have access to the actual source-code, so we can't just look the implementation-details up in case of a question). :-)

With best regards,

Lukas

Statistics: Posted by Lukas F. — Wed May 24, 2017 3:58 am


]]>
2017-05-20T22:01:54+08:00 2017-05-20T22:01:54+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=13288#p13288 <![CDATA[Documentation Request • Re: I2C Slave Mode]]> Arduino Pro Mini (3.3V, Atmega328 8Mhz) to ESP8266 (nodemcu) using the code by Divingshrek but i can't get any data transfer.

What's wrong?

connections:
ESP8266 <--> GPIO 4 (D2) SCL <==> SCL (A4) <--> PRO-MINI
ESP8266 <--> GPIO 5 (D1) SDA <==> SDA (A5) <--> PRO-MINI
pull-up 5K to VCC


MASTER (Arduino Pro Mini)

Code:

#include <Wire.h>

int x = 0;
void setup() {

 Serial.begin(9600);
  Wire.begin(8); 
}

void loop()
{
     
  Wire.beginTransmission(8);
  Wire.write(x);
  Wire.endTransmission();
  Serial.println(x);
  x++;
  delay(100);
 
}



SLAVE (ESP8266)

Code:


... code above...

unsigned int SCL_pin=4;       // SCL pin GPIO
unsigned int SDA_pin=5;       // SCL pin GPIO


int address = 8;

void receiveEvent(int howMany)
{
  Serial.println("receiveEvent()");
  while (1 < ESP_I2CSlaveavailable())
  {
    char c = ESP_I2CSlaveread();
    Serial.print(c);       
  }
}

void requestEvent()
{
  Serial.println("requestEvent()");
}


void setup()
{
    ESP_I2CSlavebegin(SCL_pin,SDA_pin,address);
    ESP_I2CSlaveonRequest(requestEvent);
    ESP_I2CSlaveonReceive(receiveEvent);
    Serial.begin(9600);
}

void loop()
{
  delay(100);
}

Statistics: Posted by biccius — Sat May 20, 2017 10:01 pm


]]>
2017-05-18T13:55:57+08:00 2017-05-18T13:55:57+08:00 https://bbs.espressif.com:443/viewtopic.php?t=1923&p=13226#p13226 <![CDATA[Documentation Request • When is SPI MISO sampled]]>
During an SPI conversation. I need to pause code execution after I send out a byte until the Pics MISO pin goes HIGH.

I have tried all manner of read syntax and can not seem to prove or disprove that I can read the value of this SPI data line while the SPI is active.

Can anyone tell me if this is possible and what code does this.

In an attempt to create a loop that will work without answering that question, I tried turning off the SPI, reassign pin 37 as input, loop until it goes HIGH and then turn SPI back on.

I can not even get this loop to work, any ideas?

Here is the code that should work:Code:

Statistics: Posted by Kallapser — Thu May 18, 2017 1:55 pm


]]>
2017-05-14T20:43:10+08:00 2017-05-14T20:43:10+08:00 https://bbs.espressif.com:443/viewtopic.php?t=4321&p=13102#p13102 <![CDATA[Documentation Request • Re: Boot process / flash / rom]]> Is your program THAT large?
If you just want to store data for most of the part, you may try setting flash size as 32MBit in flash tool and use the 4MB flash map.
But during execution, you should be able to access the remaining 12MB in code.
So if you just need the size for storing data, this should be fine.

If you need to store executable code in space over 4MB, let me know, I will ask relevant people internally and get back to you.

Statistics: Posted by Guest — Sun May 14, 2017 8:43 pm


]]>
2017-05-06T07:30:25+08:00 2017-05-06T07:30:25+08:00 https://bbs.espressif.com:443/viewtopic.php?t=4321&p=12838#p12838 <![CDATA[Documentation Request • Boot process / flash / rom]]>
I am missing information about the boot process, especially the interaction with the flash.
Specifically, I am trying to boot the esp8266 from a 128MBit flash.

What I understand is, that there is code in the ROM within the esp8266, which, upon power-up, reads the first block of the flash via SPI.
In that block we have 2 bytes (at position 2 and 3).
Their meaning is (found elsewhere in this forum):

==============================
# SPI FLASH PARAMS
#-------------------
#flash_mode=
# 0: QIO
# 1: QOUT
# 2: DIO
# 3: DOUT
#-------------------
#flash_clk_div=
# 0 : 80m / 2
# 1 : 80m / 3
# 2 : 80m / 4
# 0xf: 80m / 1
#-------------------
#flash_size=
# 0 : 512 KB
# 1 : 256 KB
# 2 : 1024 KB
# 3 : 2048 KB
# 4 : 4096 KB
#-------------------
# END OF SPI FLASH PARAMS
#============================
byte2=int(flash_mode)&0xff
byte3=(((int(flash_size)<<4)| int(flash_clk_div))&0xff)


Now what is left unclear in the documentation is

1) in which flash_mode and clock frequency does the ROM load the initial sector 0 ?

2) what happens after the rom has loaded this sector? (I would have expected it to start executing whatever code is contained in that sector, but instead it seems to search within the flash for other code at semi-random addresses and does not execute the code).

3) assuming the ROM searches the flash for other valid code, how are these addresses determined?

4) I believe the flash size is significant, for the ROM to determine which address the code is expected. If so, is the size of the flash determined by flash_size (byte 3) in sector 0, or does the ROM use "Common Flash Interface" to determine the flash size?

5) what is the criteria for the ROM to decide wether or not it found valid code at a given address?

6) Whilst the chip is capable of QUOT the required connections are not made. Will the ROM honour the flash_mode setting in byte 2 when searching for code in the flash?)

7) Which functions are available within the ROM and could you please document that API. (not the SDK - that is well enough documented - I am looking for the functions within the ROM)

8) Given that above table only goes upto 4 Megabyte / 32mbit: what value should I set flash_size on a 128mbit flash?

Thanks,


Conrad

the flash chip is this one:
https://www.digikey.com/product-detail/ ... ND/3874288

Statistics: Posted by SingingCat — Sat May 06, 2017 7:30 am


]]>
2017-04-16T14:25:01+08:00 2017-04-16T14:25:01+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2537&p=12346#p12346 <![CDATA[Documentation Request • Re: TIMERS]]> Statistics: Posted by magres — Sun Apr 16, 2017 2:25 pm


]]>
2017-03-06T17:02:37+08:00 2017-03-06T17:02:37+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2537&p=11434#p11434 <![CDATA[Documentation Request • Re: TIMERS]]> I've gone through hardware timer APIs in 8266 API guide, but still from it and given sample code in hw_timer.c and .h files, i'm not clear about hardware timer's operations. earlier it was mentioned like detailed documents would be released soon. so is there any reference material available for further understanding? or i'm left with that API guide and hw_timer.c and .h, provided in SDK, only?

i'd appreciate your help or advice.

Statistics: Posted by rajkumar patel — Mon Mar 06, 2017 5:02 pm


]]>
2017-02-13T14:33:26+08:00 2017-02-13T14:33:26+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=11308#p11308 <![CDATA[Documentation Request • Re: I2C Slave Mode]]> http://www.esp8266.com/viewtopic.php?f= ... d30b106aae

Statistics: Posted by Guest — Mon Feb 13, 2017 2:33 pm


]]>
2017-02-06T09:21:15+08:00 2017-02-06T09:21:15+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=11239#p11239 <![CDATA[Documentation Request • Re: I2C Slave Mode]]> Still have a few bits and pieces to test so consider it a work in progress. My intention was to turn it into a library at some point hence the long public method names beginning with "ESP_I2CSlave". Looking at this forum it would appear I'll need to change the GPIO reads/writes into ASM for speed...but the code is prob too long for an ISR anyway.

Any constructive comments welcome...and any hints how to join the forum too :D

Cheers
Ian


Code:

/* I2C Slave
 * 

 */

// States
// ======
#define IDL 0x01        // IDL - Idle state
#define SLA 0x02        // SLA - Receiving SLA from master
#define ACK 0x04        // ACK - Sending ACK tomaster
#define NAK 0x08        // NAK - Sending NACK to master
#define RAK 0x10        // RAK - Receiving ACK/NACK from master
#define RCD 0x20        // RCD - Receiving data from master
#define SND 0x40        // SND - Sending data to master

// Flags
// =====
#define STOP 0x01       // STOP - STOP signal detected
#define STRT 0x02       // STRT - START signal detected
#define SLAW 0x04       // SLAW - SLA+W matched our slave address
#define SLAR 0x08       // SLAR - SLA+R matched our slave address
#define BFUL 0x10       // BFUL - I2C buffer full
#define BEMP 0x20       // BEMP - I2C buffer empty

// Pin Defs
unsigned int SCL_pin=4;       // SCL pin GPIO
unsigned int SDA_pin=5;       // SCL pin GPIO

// macros to avoid using digital write and read (speed up as everything is interrupt driven)
#define SCL_LOW GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS,1<< SCL_pin)
#define SCL_HIGH GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS,1<< SCL_pin)
#define SDA_LOW GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS,1<< SDA_pin)
#define SDA_HIGH GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS,1<< SDA_pin)
#define READ_SCL GPIO_REG_READ(GPIO_IN_ADDRESS)&(1<<SCL_pin)
#define READ_SDA GPIO_REG_READ(GPIO_IN_ADDRESS)&(1<<SDA_pin)

// buffer defs
#define BUFF_ERR 0xffffffff       // error code to return if trying to read from an empty buffer or write to full buffer
#define I2CBUFFLEN 32            // buffer size
#define BUFF_READ 0x01            // read buffer item
#define BUFF_WRITE 0x02           // write to buffer
#define BUFF_AVAIL 0x03           // how many items in the buffer
#define BUFF_FLUSH 0x04           // flush the buffer

// misc defs
#define FUNC_RST 1                // used to reset static vars in send/receive functions
#define FUNC_NOT_RST 0            // opposite of FUNC_RST

// global vars (native 32 bit and unsigned for speed)
volatile unsigned int Flags=STOP, State=IDL;
void (*user_onRequest)(void);
void (*user_onReceive)(int);
volatile unsigned int _I2CAddress=0x3f;


void setup() {
}

void loop() {
}

////////////////////////////////////////////////////////////////////////
//
// PRIVATE METHODS
//
////////////////////////////////////////////////////////////////////////

unsigned int PRIV_I2CBuffer(unsigned int _action, unsigned int &_val)
{
  volatile static unsigned int _BuffHead=0, _BuffTail=0, _Buffer[I2CBUFFLEN];

  switch (_action) {
    case BUFF_READ:
      if (Flags & BEMP) return false;
      _val = _Buffer[_BuffTail];
      _BuffTail++;
      if (_BuffTail >= I2CBUFFLEN) _BuffTail = 0;
      if (_BuffTail == _BuffHead) Flags |= BEMP;
      else Flags &= ~BEMP;
      Flags &= ~BFUL;
      break;
    case BUFF_WRITE:
      if (Flags & BFUL) return false;
      _Buffer[_BuffHead] = _val;
      _BuffHead++;
      if (_BuffHead >= I2CBUFFLEN) _BuffHead = 0;
      if (_BuffHead == _BuffTail) Flags |= BFUL;
      else Flags &= ~BFUL;
      Flags &= ~BEMP;
      break;
    case BUFF_AVAIL:
       if (Flags & BFUL) _val = I2CBUFFLEN;
       else _val = (_BuffHead >= _BuffTail)?_BuffHead - _BuffTail:I2CBUFFLEN - _BuffTail + _BuffHead;
      break; 
    case BUFF_FLUSH:
      _BuffHead = 0;
      _BuffTail = 0;
      Flags |= BEMP;
      Flags &= ~BFUL;
      break;
  }
  return true;
}

void onReceiveService(int numBytes)
{
  // don't bother if user hasn't registered a callback
  if(!user_onReceive) return;
  // alert user program
  user_onReceive(numBytes);
}

void onRequestService(void){
  // // don't bother if user hasn't registered a callback
  if(!user_onRequest) return;
  // alert user program
  user_onRequest();
}

void PRIV_RAKhandler()
{
  // nice and easy if we get ACK send more data otherwise stop
  if (READ_SDA) PRIV_STOPhandler();
  else State = SND;
}

void PRIV_NAKhandler()
{
  // nice and simple if we NACK the next response should
  // be stop or start both of which will reset the state
  SDA_HIGH;
}

void PRIV_ACKhandler()
{
  volatile static unsigned int _firstpass = 1;
  if (_firstpass) {
    SDA_LOW;
    _firstpass = 0;
  }
  else {
    SDA_HIGH;
    _firstpass = 1;
    if (Flags & SLAW) State = RCD;
    else {
      State = SND;
      PRIV_SNDhandler(FUNC_NOT_RST);
    }
  }
}

void PRIV_RCDhandler(unsigned int _reset)
{
  volatile static unsigned int _bitcount=0, _i2cbyte=0, _firstpass=1;
  unsigned int _val;
  if (_reset) {
    _firstpass = 1;
    _bitcount = 0;
    _i2cbyte = 0;
    return;
  }
  if (_firstpass) {
    _firstpass = 0;
    _bitcount = 0;
    _i2cbyte = 0;
  }
  _i2cbyte <<= 1;
  if (READ_SDA) _i2cbyte |= 1;
  _bitcount++;
  if (_bitcount > 7) {
    _firstpass = 1;
    _val = _i2cbyte;
    if (!PRIV_I2CBuffer(BUFF_WRITE, _val)) State = NAK;
    else {
      if (Flags & BFUL) State = NAK;
      else State = ACK;
    }
  }
}

void PRIV_SLAhandler(unsigned int _reset)
{
  volatile static unsigned int _bitcount=0, _i2cbyte, _firstpass = 1;
    if (_reset) {
    _firstpass = 1;
    _bitcount = 0;
    _i2cbyte = 0;
    return;
  }
  if (_firstpass) {
    _firstpass =0;
    _bitcount = 0;
    _i2cbyte = 0;
  }
  _i2cbyte <<= 1;
  if (READ_SDA) _i2cbyte |= 1;
  _bitcount++;
  if (_bitcount > 7) {
    _firstpass = 1;
     if ((_i2cbyte >> 1) == _I2CAddress) {
      if (_i2cbyte & 0x01) {
        Flags |= SLAR;
        onRequestService();
        if (Flags & BEMP) State = NAK;
        else State = ACK;
      }
      else Flags|= SLAW;
      if (Flags & BFUL) State = NAK;
      else State = ACK;
    }
  }
}

void PRIV_SNDhandler(unsigned int _reset)
{
  volatile static unsigned int _bitcount=0, _i2cbyte, _releaseSDA=0, _firstpass = 1;
  unsigned int _val;
    if (_reset) {
    _firstpass = 1;
    _bitcount = 0;
    return;
  }
  if (_releaseSDA) {
    SDA_HIGH;
    State = RAK;
    _releaseSDA = 0;
    _firstpass = 1;
    return;
  }
  if (!_firstpass) {
    PRIV_I2CBuffer(BUFF_READ, _val);
    _i2cbyte = _val;
    _bitcount = 0;
    _firstpass = 0;
  }
  if (_i2cbyte & 1) SDA_HIGH;
  else SDA_LOW;
  _i2cbyte >>= 1;
  _bitcount++;
  if (_bitcount > 7) {
     _releaseSDA = 1;
  }
}

void PRIV_STRThandler()
{
  unsigned int _retval, _val;
  if (Flags & SLAW) {
    PRIV_I2CBuffer(BUFF_AVAIL, _val);
    if (_val) onReceiveService(_val);
  }
  if (Flags & SLAR) PRIV_I2CBuffer(BUFF_FLUSH, _val);
  Flags &= 0xfffffff0;
  Flags |= STRT;
  State = SLA;
}

void PRIV_STOPhandler()
{
  unsigned int _retval, _val;
  if (Flags & SLAW) {
    PRIV_I2CBuffer(BUFF_AVAIL, _val);
    if (_val) onReceiveService(_val);
    PRIV_RCDhandler(FUNC_RST);
    PRIV_SNDhandler(FUNC_RST);
    PRIV_SLAhandler(FUNC_RST);
  }
  if (Flags & SLAR) PRIV_I2CBuffer(BUFF_FLUSH, _val);
  Flags &= 0xfffffff0;
  Flags |= STOP;
  State = IDL;
}

void PRIV_SCLChangeISR()
{
  if (State == IDL) return;

  if (READ_SCL) {            //read on rising edge
    switch (State) {
      case RAK:
        // receiving ACK from master
        PRIV_RAKhandler();
        break;
      case RCD:
        // receiving data from master
        PRIV_RCDhandler(FUNC_NOT_RST);
        break;
      case SLA:
        // receiving SLA+R/W from master
        PRIV_SLAhandler(FUNC_NOT_RST);
        break;
    }
  }
  else {                    // Sending data to master
    SCL_LOW;                // Apply Clock Stretch
    switch (State) {
      case ACK:
        // send ack to master
        PRIV_ACKhandler();
        break;
      case NAK:
        // send nack to master
        PRIV_NAKhandler();
        break;
      case SND:
        // send data to master
        PRIV_SNDhandler(FUNC_NOT_RST);
        break;
    }
    SCL_HIGH;              // Release Clock Stretch
  }
}

void PRIV_SDAChangeISR()
{
  if (READ_SCL) {
    if (READ_SDA) PRIV_STOPhandler();
    else PRIV_STRThandler();
  }
}

////////////////////////////////////////////////////////////////////////////////
//
//   PUBLIC METHODS
//
///////////////////////////////////////////////////////////////////////////////

unsigned int ESP_I2CSlavewrite(unsigned int _val)
{
  unsigned int _retval;

  if (Flags & BFUL) return BUFF_ERR;
  _retval = PRIV_I2CBuffer(BUFF_WRITE, _val);
  return (_retval)?0:BUFF_ERR;
}

unsigned int ESP_I2CSlaveread()
{
  unsigned int _retval, _val;
  if (Flags & BEMP) return BUFF_ERR;
  _retval = PRIV_I2CBuffer(BUFF_READ, _val);
  return (_retval)?_val:BUFF_ERR;
}

void ESP_I2CSlaveflush()
{
  unsigned int _retval,  _val;
  PRIV_I2CBuffer(BUFF_FLUSH, _val);
}

unsigned int ESP_I2CSlaveavailable()
{
  unsigned int _retval, _val;
  _retval = PRIV_I2CBuffer(BUFF_AVAIL, _val);
  return _val;
}

void ESP_I2CSlaveonReceive( void (*function)(int) ){
  user_onReceive = function;
}

void ESP_I2CSlaveonRequest( void (*function)(void) ){
  user_onRequest = function;
}

void ESP_I2CSlavebegin(int scl_pin, int sda_pin, byte address)
{
  _I2CAddress = address & 0x7f;
  SCL_pin = scl_pin & 0xf;
  SDA_pin = sda_pin & 0xf;
  pinMode(SCL_pin, OUTPUT_OPEN_DRAIN);
  pinMode(SDA_pin, OUTPUT_OPEN_DRAIN);
  SCL_HIGH;
  SDA_HIGH;
  attachInterrupt(digitalPinToInterrupt(SCL_pin), PRIV_SCLChangeISR, CHANGE);
  attachInterrupt(digitalPinToInterrupt(SDA_pin), PRIV_SDAChangeISR, CHANGE);
}

Statistics: Posted by Guest — Mon Feb 06, 2017 9:21 am


]]>
2017-01-05T16:36:26+08:00 2017-01-05T16:36:26+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=11031#p11031 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
yes that's true. But this is depending on the used SDK if this IRAM_ATTR is necessary. As far as I know the IRAM_ATTR is the default for NONOS SDK. if you use RTOS SDK it must be added.

Statistics: Posted by dkaufmann — Thu Jan 05, 2017 4:36 pm


]]>
2016-11-30T19:54:46+08:00 2016-11-30T19:54:46+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10734#p10734 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
What I noticed about your code is you were using a full blown C function call to request the pin value instead of the ASM call that the examples were using; that "CALL" and "RTN" will add time.

I'm not sure it will help, but I've read that also using the IRAM_ATTR flag is typically considered good practice for fast/short ISRs.

Statistics: Posted by Guest — Wed Nov 30, 2016 7:54 pm


]]>
2016-11-29T20:54:09+08:00 2016-11-29T20:54:09+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10728#p10728 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
okay. I still have no idea how to enter the interrupt routine faster. If I enter the ISR() on falling edge SDA and measure the SCL line, SCL has already changed to the next state. It is just not a real "interrupt" for me if it takes that long. DMA is no option for a simple I2C slave.

best regards
Dominik

Statistics: Posted by dkaufmann — Tue Nov 29, 2016 8:54 pm


]]>
2016-11-26T05:31:50+08:00 2016-11-26T05:31:50+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10674#p10674 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
dkaufmann wrote:
Hi Rudi,

i am very interested in these ASM instruction to run the I2C faster. I'd like to run in high speed mode or at least >100kHz.

is this line to read the inputs? how exactly?
_l8ui a0, a11, GPIO_OFFSET_INPUT


hi dominik

ah you use the code from CNLohr :D
yes, asked you, do you know about this in prev postings..


the thing is not bad, but the 17 cycles is too much too.
CNLohr on esp8266.com wrote:
I could respond to interrupt requests in .28 us!


then you know about my state to this too

rudi on esp8266.com wrote:
with 80MHz it is 12.5 ns
with 160 MHz it is 6.5 ns ( had measuring on time this by 6.2 ns - see picture )

fastest:
instructions: 4

80 MHz : 12.5ns * 4 = 50 ns
160 MHz : 6.5 ns * 4 = 26 ns ( 6.25 * 4 = 25 ns )

optimated
instructions: 8

80 MHz : 12.5ns * 8 = 100 ns
160 MHz : 6.5 ns * 8 = 52 ns ( 6.25 * 8 = 50 ns )

and does a little be more better as your cool thing with .28 us ( 280 ns )

..

state to high speed usb:
-------------------------------

without DMA and Core 160MHz
without drops - tricks
and with asm blocks

custom Instructions: 6.25ns
bit flow for 1 bit data read:
---------------------------

ISR Fired:
fired 6.25
nop 6.25
clear 6.25
nop 6.25
attach 6.25
nop 6.25


Clock:
low 6.25
nop 6.25
high 6.25
nop 6.25



Data read:
get pin 6.25
nop 6.25
shift pin 6.25
nop 6.25

-----------------------------

14 * 6.5 87.5 ns ( full clock )

87.5 ns * 8 = 700 ns

8 Bit = 0.700 us

1 ms = 1000 * 8 / 0.700 = 11428 Bit / ms

1 s 11428 * 1000 = 11 428 000 Bit/s

11 428 000 Bit/s = 11.428 MBit/s




example:
you can work helped with
"for while (..)"

Code:

static inline unsigned get_ccount(void)
{
        unsigned r;
        asm volatile ("rsr %0, ccount" : "=r"(r));
        return r;
}




backgrounds:

-> http://naberius.de/2015/05/14/esp8266-g ... rformance/
-> viewtopic.php?t=979


the interrupt delay or the GPIO read is too slow. even without debug prints. how do you read/set the GPIO in assembler? in your code I see you use the "normal" GPIO_INPUT_GET function. this is much too slow even with 160MHz. Do you agree?


Yes - there are to much instructions


Can you show me how you do it faster?


using DMA and ticks on 6.5 ns

a good example is done by CNLohr with Broadcast TV and driving WS2812

i am just in time on esp32 CAN theme
perhabs will come back again to this i2c slave theme..

best wishes
rudi ;-)

Statistics: Posted by rudi — Sat Nov 26, 2016 5:31 am


]]>
2016-11-24T15:13:59+08:00 2016-11-24T15:13:59+08:00 https://bbs.espressif.com:443/viewtopic.php?t=3112&p=10634#p10634 <![CDATA[Documentation Request • Re: ESP8266天线阻抗匹配]]> 在0a-esp8266ex_datasheet中第五页管脚定义2脚表述为芯片输出阻抗为50欧姆是一个静态的,请以esp8266-hardware_matching_guide中天线匹配部分说ESP8266 PA 输出阻抗为39-j6为准。
谢谢你对ESP8266的关注。

Statistics: Posted by ESP_Xutao — Thu Nov 24, 2016 3:13 pm


]]>
2016-11-22T15:44:28+08:00 2016-11-22T15:44:28+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10610#p10610 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
i am very interested in these ASM instruction to run the I2C faster. I'd like to run in high speed mode or at least >100kHz.

is this line to read the inputs? how exactly?
_l8ui a0, a11, GPIO_OFFSET_INPUT

"if i delete the debug prints i can go on to 400 KHz with 160 MHz CPU":
the interrupt delay or the GPIO read is too slow. even without debug prints. how do you read/set the GPIO in assembler? in your code I see you use the "normal" GPIO_INPUT_GET function. this is much too slow even with 160MHz. Do you agree? Can you show me how you do it faster?

Thank you

Dominik

Statistics: Posted by dkaufmann — Tue Nov 22, 2016 3:44 pm


]]>
2016-11-21T16:47:12+08:00 2016-11-21T16:47:12+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10598#p10598 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
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:

// ---------------- 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));
   }

Statistics: Posted by dkaufmann — Mon Nov 21, 2016 4:47 pm


]]>
2016-11-18T15:17:51+08:00 2016-11-18T15:17:51+08:00 https://bbs.espressif.com:443/viewtopic.php?t=3112&p=10579#p10579 <![CDATA[Documentation Request • ESP8266天线阻抗匹配]]> 我在设计硬件时,看0a-esp8266ex_datasheet中第五页管脚定义2脚表述为芯片输出阻抗为50欧姆,无需对芯片进行匹配;
然而在看文档esp8266-hardware_matching_guide中天线匹配部分说ESP8266 PA 输出阻抗为39+j6;
上面两个文档好像有点矛盾,以哪个为准?
最后,谢谢!

Statistics: Posted by greatz.yu — Fri Nov 18, 2016 3:17 pm


]]>
2016-11-09T04:44:27+08:00 2016-11-09T04:44:27+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2192&p=10469#p10469 <![CDATA[Documentation Request • Re: Certification]]> We need to build a custom firmware, because our product has a watchdog and needs to be reset in interval of 60s. For certification, it must work in b,g,n mode and duty cycle 98%. Could you help us?
PS. I've tried work with your binary file, but didn't have success.

Thanks.

Statistics: Posted by L@S — Wed Nov 09, 2016 4:44 am


]]>
2016-11-05T05:06:59+08:00 2016-11-05T05:06:59+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10410#p10410 <![CDATA[Documentation Request • Re: I2C Slave Mode]]> Statistics: Posted by martinayotte — Sat Nov 05, 2016 5:06 am


]]>
2016-11-03T16:58:25+08:00 2016-11-03T16:58:25+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10401#p10401 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
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!!

Statistics: Posted by Guest — Thu Nov 03, 2016 4:58 pm


]]>
2016-11-01T01:58:10+08:00 2016-11-01T01:58:10+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10367#p10367 <![CDATA[Documentation Request • Re: I2C Slave Mode]]> 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 ...

Statistics: Posted by martinayotte — Tue Nov 01, 2016 1:58 am


]]>
2016-10-28T22:24:05+08:00 2016-10-28T22:24:05+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10334#p10334 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
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

Statistics: Posted by rudi — Fri Oct 28, 2016 10:24 pm


]]>
2016-10-28T22:05:08+08:00 2016-10-28T22:05:08+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10332#p10332 <![CDATA[Documentation Request • Re: I2C Slave Mode]]> Statistics: Posted by martinayotte — Fri Oct 28, 2016 10:05 pm


]]>
2016-10-28T00:58:57+08:00 2016-10-28T00:58:57+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10310#p10310 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
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 ;-)

Statistics: Posted by rudi — Fri Oct 28, 2016 12:58 am


]]>
2016-10-28T00:21:18+08:00 2016-10-28T00:21:18+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10309#p10309 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
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 ?

Statistics: Posted by martinayotte — Fri Oct 28, 2016 12:21 am


]]>
2016-10-27T01:22:19+08:00 2016-10-27T01:22:19+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10281#p10281 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
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 ;-)

Statistics: Posted by rudi — Thu Oct 27, 2016 1:22 am


]]>
2016-10-26T22:46:14+08:00 2016-10-26T22:46:14+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10280#p10280 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
okay I see. thanks for this one. Gonna try it out.

best regards
D.

Statistics: Posted by dkaufmann — Wed Oct 26, 2016 10:46 pm


]]>
2016-10-26T22:01:04+08:00 2016-10-26T22:01:04+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10279#p10279 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
dkaufmann wrote:
Hi Rudi,

I'm surprised that you manage to reach 400kHz with your method. When I implemented the interrupt driven version (with SCL and SDA interrupt), it already stopped to work with 100kHz. The interrupt latency was too high. From 100kHz I started to miss the next edge (from rising to the next falling edge on SCL). Do you have an idea why? (my ESP8266 runs with 80MHz which should be fast enough).

Thanks for the help.

best regards
D.


Yes you are right!
my fastest with this v 0.1 methode is 120..KHz
in the others i use asm instruction because the gpio switch is very slow, and ( i think it was the ESP-04 for best result ) if you take difference ESP modules there can be time difference in switching ( capazitors on gpio=bad idea )

do you know

Code:


_l8ui a0, a11, GPIO_OFFSET_INPUT



or
example precise timing..

Code:


static inline unsigned get_ccount(void)
{
        unsigned r;
        asm volatile ("rsr %0, ccount" : "=r"(r));
        return r;
}



with 80MHz it is 12.5 ns
with 160 MHz it is 6.5 ns ( had measuring on time this by 6.2 ns - see picture in this thread i started long time ago)
just in time i maked a pause on this, in the past last year in spring, i wrote things here:
http://www.mikrocontroller.net/topic/358654

fastest:
instructions: 4

80 MHz : 12.5ns * 4 = 50 ns
160 MHz : 6.5 ns * 4 = 26 ns ( 6.25 * 4 = 25 ns )

optimated
instructions: 8

80 MHz : 12.5ns * 8 = 100 ns
160 MHz : 6.5 ns * 8 = 52 ns ( 6.25 * 8 = 50 ns )

and does a little be more better as usually doings on int ( 280 ns )

perhabs go on again on this , there are many question open to this theme,
i had paused because there was no (germany) community interrest on this last year -
my favority doing in this was usb host :)

Charles works on USB with asm instruction too. here is my statement to his doing.
http://www.esp8266.com/viewtopic.php?f= ... 275#p52980

the theme is DMA, too. but this is an other theme.

with the "trick" you can do a timing on this:

Code:

..
t1 = system_get_time();     // API get time
// start
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag / call and get
while (mtick < 100 )
{
// empty
mtick++;
}

t2 = system_get_time();     // API get time
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht / how many ticks used..
..


and then you can handle fine.
..but you must work with 160 MHz..

best wishes
rudi ;-)

Statistics: Posted by rudi — Wed Oct 26, 2016 10:01 pm


]]>
2016-10-26T19:55:50+08:00 2016-10-26T19:55:50+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10278#p10278 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
I'm surprised that you manage to reach 400kHz with your method. When I implemented the interrupt driven version (with SCL and SDA interrupt), it already stopped to work with 100kHz. The interrupt latency was too high. From 100kHz I started to miss the next edge (from rising to the next falling edge on SCL). Do you have an idea why? (my ESP8266 runs with 80MHz which should be fast enough).

Thanks for the help.

best regards
D.

Statistics: Posted by dkaufmann — Wed Oct 26, 2016 7:55 pm


]]>
2016-10-26T17:55:33+08:00 2016-10-26T17:55:33+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10277#p10277 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
dkaufmann wrote:
Hi Rudi,

a lot of comments :). Thanks for your review. In which case it happens, that a stop comes from the master after sending the address? I will add a general interrupt on the STOP signal, too. So I can stop the whole communication independent of the state.
Thus, I also had a version with SCL and SDA interrupt (without while loops). The problem was, that it was too slow for 100 kHz. This is why I changed my code to only Start interrupt and then stay in the ISR.
Sorry, implementation of a master is not planned at the moment. (not needed in my project, and no time at the moment.) If I do later, I'll post it.

have a nice one!


;-)
if the master break example the communication - you must "agieren" and "handle" this.
so my "teaching steps" was bit for bit in cases...

yes you right, your doing is faster in this part, my doing with int on sda + scl makes the slave slower but exactly.
and the prints do make isr slower too. so this is going well do 25 Khz with debug prints..
if i delete the debug prints i can go on to 400 KHz with 160 MHz CPU

this was the v 0.1 ;-) so never push your last version you work on :)
this only for teach / follow steps for understanding... ;-) ( Opendrain, ACK, Start, Stop ..)

the homework must be done by the user.
i like your version.
i like the mine too :)

best wishes
rudi ;-)

Statistics: Posted by rudi — Wed Oct 26, 2016 5:55 pm


]]>
2016-10-26T17:15:12+08:00 2016-10-26T17:15:12+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10276#p10276 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
a lot of comments :). Thanks for your review. In which case it happens, that a stop comes from the master after sending the address? I will add a general interrupt on the STOP signal, too. So I can stop the whole communication independent of the state.
Thus, I also had a version with SCL and SDA interrupt (without while loops). The problem was, that it was too slow for 100 kHz. This is why I changed my code to only Start interrupt and then stay in the ISR.
Sorry, implementation of a master is not planned at the moment. (not needed in my project, and no time at the moment.) If I do later, I'll post it.

have a nice one!

Statistics: Posted by dkaufmann — Wed Oct 26, 2016 5:15 pm


]]>
2016-10-26T05:05:30+08:00 2016-10-26T05:05:30+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10268#p10268 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>
dkaufmann wrote:
plus open drain config of the SDA/SCL pins
..



yep da kemma zam :) geht doch.
why ? ( ~PERIPHS_IO_MUX_MTMS_U and PERIPHS_IO_MUX_MTDI_U ./. PERIPHS_IO_MUX_MTCK_U )

Code:

// PIN SETUP..
// (c) dkaufmann, 25.10.2016, Zürich, Switzerland

//SDA on GPIO12
#define I2C_SDA_PIN 12
#define I2C_SDA_MUX PERIPHS_IO_MUX_MTDI_U
#define I2C_SDA_FUNC FUNC_GPIO12

//SCK on GPIO14
#define I2C_SCK_PIN 14
#define I2C_SCK_MUX PERIPHS_IO_MUX_MTMS_U
#define I2C_SCK_FUNC FUNC_GPIO14



Code:

// rudi
// header
#define I2C_SLAVE_SDA_MUX PERIPHS_IO_MUX_MTMS_U  //CONFIG THE GPIO MUX HERE
#define I2C_SLAVE_SDL_MUX PERIPHS_IO_MUX_MTCK_U  //CONFIG THE GPIO MUX HERE
#define I2C_SLAVE_SDA_GPIO 12 //CONFIG THE GPIO NUMBER HERE
#define I2C_SLAVE_SDL_GPIO 14 //CONFIG THE GPIO NUMBER HERE


// c.file
//SET_PERI_REG_MASK(I2C_SLAVE_SDA_MUX, 0x30);
WRITE_PERI_REG(I2C_SLAVE_SDA_MUX, (READ_PERI_REG(I2C_SLAVE_SDA_MUX)&0xfffffe0f)|0x30);

//SET_PERI_REG_MASK(I2C_SLAVE_SDL_MUX, 0x30);
WRITE_PERI_REG(I2C_SLAVE_SDL_MUX, (READ_PERI_REG(I2C_SLAVE_SDL_MUX)&0xfffffe0f)|0x30);




OpenDrain


Code:


// (c) dkaufmann, 25.10.2016, Zürich, Switzerland
//Set SDA as open drain
    GPIO_REG_WRITE(
        GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SDA_PIN)),
        GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SDA_PIN))) |
        GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)
    );
    GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_SDA_PIN));
    GPIO_OUTPUT_SET(I2C_SDA_PIN, 1);

    //Set SCK as open drain
    GPIO_REG_WRITE(
        GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SCK_PIN)),
        GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SCK_PIN))) |
        GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)
    );
    GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_SCK_PIN));
    GPIO_OUTPUT_SET(I2C_SCK_PIN, 1);



Code:

   
   // rudi
   GPIO_REG_WRITE(
      GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO)),
      GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO)))|
      GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE));//open drain;
   
   GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS,GPIO_REG_READ(GPIO_ENABLE_ADDRESS)|(1<<I2C_SLAVE_SDA_GPIO) );
    // set..step later
   
   
    GPIO_REG_WRITE(
      GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO)),
      GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO)))|
      GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE));//open drain;
   
   GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS,GPIO_REG_READ(GPIO_ENABLE_ADDRESS)|(1<<I2C_SLAVE_SDL_GPIO) );
   // set..step later
   
   
   
   // set pins high
   // header
   #define I2C_SLAVE_GPIO_SET(pin)  \
        gpio_output_set(1<<pin,0,1<<pin,0)

    #define I2C_SLAVE_GPIO_CLR(pin) \
        gpio_output_set(0,1<<pin,1<<pin,0)
      
   #define I2C_SLAVE_GPIO_OUT(pin,val) \
        if(val) I2C_SLAVE_GPIO_SET(pin);\
        else I2C_SLAVE_GPIO_CLR(pin)
   
   
   // c.file
   I2C_SLAVE_GPIO_SET(I2C_SLAVE_SDA_GPIO);
    I2C_SLAVE_GPIO_SET(I2C_SLAVE_SDL_GPIO);




tests..

Code:

// rudi

//for test
void read_gpio_sta()
{

    ets_printf("gpio in reg   :  0x%08x\n",GPIO_REG_READ(GPIO_IN_ADDRESS));
    ets_printf("gpio out reg  :  0x%08x\n\n",GPIO_REG_READ(GPIO_OUT_ADDRESS));

    ets_printf("sda reg set   :  0x%08x \n",GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO))) );
    ets_printf("sdl reg set   :  0x%08x \n",GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO))) );

}




the isr comes asap i must clean my code,
it is longer :) your ISR looks not bad - but i think you get a problem, if the master send the addr and then a stop,
you have no routine for this; i will check your isr ,, have seen the reply and have done reply fast.


@apollo0226
where is your code?
work in this and i am sure you will do it too,
the important things is, opendrain and ack doing.
now you have this in two difference ways.
because i do step by step ( bit by bit ) in the debug code..
i allways check in this debug version 0.1 each int fire for start, stop..
and i do this difference to switzerland.
switzerland use a "while on the scl"
i use interrupt on SDA and SCL
this is the difference.

now go on guy!


edit ..isr...

Code:


// **************************************************
// (c) eMbeddedHome rudi ;-)  07.May 2016
// **************************************************
//**    v.0.1
//**    ISR for SDA and SCL
//**    ===================
//**    simple protokol
//**   Master send Start
//**    Master send addr - Slave check it with ACK/NACK
//**   if a write command
//**    Master send data - Slave receive it
//**   Master send Stop
// **************************************************


void i2c_slave_isr() {
   
   u8 scl=0;
   u8 sda=0;
   u32 gpio_status = 0;

   // welchen read/write Status?
   static u8 write_read=0;

   // LAST
   // 0 = mehr daten
   // 1 = waren letze daten
   static nLast = 1; // vorgabe mal explizit

   gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
   ETS_GPIO_INTR_DISABLE() ;
   
   scl=GPIO_INPUT_GET(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO));
   sda=GPIO_INPUT_GET(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO));
   
   // ets_printf("ISR fired..\n\0");
   // ets_printf("%lu fired\n\0", gpio_status);


if(( (gpio_status>>I2C_SLAVE_SDA_GPIO)& BIT0)&&scl) //SDA trigger and sdl high   
{
           if( sda )// sda posedge , stop
            {
            ets_printf("stop..\n\0");
         //    if (startphase == 0) {
         //*   I2C_SLAVE_STATE = I2C_SLAVE_STATE_IDLE;
            
                I2C_SLAVE_NEXTSTEP = nsWAITING_IDLE;
                gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_NEGEDGE);
                gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_DISABLE);
            ; // return;
         }
 
   
         else //sda negedge,start
   
         {
            ets_printf("start..\n\0");
             // if (!startphase) { startphase = 1;
             // I2C_SLAVE_STATE =  I2C_SLAVE_STATE_RX_ADDR;
            // allways at start:
            I2C_SLAVE_NEXTSTEP = nsADDR1;
            I2C_SLAVE_PING = ADI;

                gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_DISABLE);
                gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_POSEDGE);
            ; // return;
         }

     
}   

     else if ( (gpio_status>>I2C_SLAVE_SDL_GPIO)& BIT0) //SDL trigger
            
         {
       // TO DO:
       // nur antworten wenn ein START vorhanden war
       // ansonsten der SLAVE alles mitprotokolliert
      
   // .... see next part...
   // switch (I2C_SLAVE_NEXTSTEP) {
   




Code:


switch (I2C_SLAVE_NEXTSTEP) {

   case nsADDR1   :    rx_addr = 0;
                  startphase = 3;
                  rx_addr = (rx_addr << 1 ) | sda ;
                  I2C_SLAVE_NEXTSTEP = nsADDR2;
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_DISABLE);
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_POSEDGE);
                  break; // return; 

   case nsADDR2   :    rx_addr = (rx_addr << 1 ) | sda ;
                  I2C_SLAVE_NEXTSTEP = nsADDR3;
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_DISABLE);
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_POSEDGE);
                  break; // return; 
   
   case nsADDR3   :    rx_addr = (rx_addr << 1 ) | sda ;
                  I2C_SLAVE_NEXTSTEP = nsADDR4;
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_DISABLE);
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_POSEDGE);
                  break; // return;
   
   case nsADDR4   :    rx_addr = (rx_addr << 1 ) | sda ;
                  I2C_SLAVE_NEXTSTEP = nsADDR5;
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_DISABLE);
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_POSEDGE);
                  break; // return;
   
   case nsADDR5   :    rx_addr = (rx_addr << 1 ) | sda ;
                  I2C_SLAVE_NEXTSTEP = nsADDR6;
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_DISABLE);
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_POSEDGE);
                  break; // return;
   
   case nsADDR6   :    rx_addr = (rx_addr << 1 ) | sda ;
                  I2C_SLAVE_NEXTSTEP = nsADDR7;
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_DISABLE);
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_POSEDGE);
                  break; // return;
   
   case nsADDR7   :    rx_addr = (rx_addr << 1 ) | sda ;
                  I2C_SLAVE_NEXTSTEP = nsADDR8;
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_DISABLE);
                  gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_POSEDGE);
                  break; // return;
   
   case nsADDR8   :    rx_addr = (rx_addr << 1 ) | sda ;
                  // addr match
                  if ( !1 || ((rx_daten & 0xfe) == I2C_SLAVE_ADDRESS)) // write & read adress is checked here
                  
                  { // addr missmatch
                     ets_printf("rx_addr 0x%2x not match \n\0", rx_addr);
                     gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_NEGEDGE); // important thing
                     gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_DISABLE);
                     goto missmatch;
                     break;
                     }
                  else
                  {
                     ets_printf("wAdmatch:0x%2x\n\0", rx_addr);
                     I2C_SLAVE_GPIO_OUT(12,0); // send ACK low
                      rx_addr = 0;
                     // Neue VAR write_read
                     // I2C_SLAVE_COMMAND = WRITE;
                     // write_read = 1;
                     I2C_SLAVE_NEXTSTEP = nsADDR9;
                     CALLED = ad8;
                     gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_DISABLE);
                     gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_NEGEDGE); // important thing
                     }
                     break; // return;
   
   case nsADDR9   :   if(!CALLED==ad8) ets_printf("false route from %d \n\0", CALLED);
                  // GO I2C_SLAVE_GPIO_OUT(12,0);
                  
                   // check read or write
                   if ( 1 & rx_addr) // its a read from Slave by the Master
                   {
                     I2C_SLAVE_COMMAND = READ;
                     I2C_SLAVE_NEXTSTEP = nsADDR1; // bzw IDLE
                     gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_DISABLE);
                     gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_POSEDGE);
                  
                  }
                   else // its a write from Master to Slave
                   {
                     ACK1;
                     I2C_SLAVE_COMMAND = WRITE;
                     I2C_SLAVE_NEXTSTEP = nsDATA1;
                     gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDA_GPIO),GPIO_PIN_INTR_ANYEDGE); // important
                     gpio_pin_intr_state_set(GPIO_ID_PIN(I2C_SLAVE_SDL_GPIO),GPIO_PIN_INTR_POSEDGE); // important
                  }
                  break;
                  
   ...
   ...
   





Code:

 ...
 ...
 
 case nsIDLE      :   // DO NOTHING
                  ets_printf("nsIDLE\n\0");
                  break;
   
   case nsWAITING_IDLE : // nothing sollte stop werden
                  ets_printf("%d: nsWaiting_IDLE \n\0", CALLED);
                     break;
   
   
   default         :   ets_printf("default\n\0");


     }

   }

 
missmatch:

     GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
     ETS_GPIO_INTR_ENABLE() ;


}

// *******************************************
// last edit 7 May 2016
//
// *******************************************







i use example this in my i2c_slave.h file:
so you know my next cases what follows


Code:


// rudi
typedef enum{
   nsSTART,
   nsSTOP,
   nsADDR1,
   nsADDR2,
   nsADDR3,
   nsADDR4,
   nsADDR5,
   nsADDR6,
   nsADDR7,
   nsADDR8,
   nsADDR9,
   nsADDR9A,
   nsADDR10,
   nsDATA1,
   nsDATA2,
   nsDATA3,
   nsDATA4,
   nsDATA5,
   nsDATA6,
   nsDATA7,
   nsDATA8,
   nsDATA9,
   nsDATA9A,
   nsDATA10,
   nsWDATA1,
   nsWDATA2,
   nsWDATA3,
   nsWDATA4,
   nsWDATA5,
   nsWDATA6,
   nsWDATA7,
   nsWDATA8,
   nsWDATA9,
   nsWDATA10,
   nsACK_A,
   nsACK_B,
   nsNACK_A,
   nsNACK_B,
   nsLAST_ADDR,
   nsLAST_DATA,
   nsFALSE_TRIGGER,
   nsWAITING_IDLE,
   nsCHECK_ADDRESS_MATCH,
   nsIDLE
}I2C_SLAVE_STEPS;

typedef enum {
   WRITE,
   READ,
   IDLE
} I2C_SLAVE_COMMANDS;

// rudi
// simple
#define I2C_START_DEDECTED 1
#define I2C_STOP_DEDECTED  2
#define I2C_ADDR_MISMATCH 3
#define I2C_SLAVE_ADDRESS  0x30
#define SINGLE 1 // in this code, one Byte transfer -> means SendStart SendAddr, SendByte, SendStop





@dkaufmann
do you have a master code too?
can you create and select for master 10Khz example? ( not faster because debug prints in the isr )
and for address example 0x30
master read one byte ( Last = 1 )
i build the slave and i give you then the value of read counter back
this means that we do the things like this:

while( ( counter <=255) ) {
// addr.
master -> uart("count: %d\n", (uint16*) counter )
master -> start
master -> send adr + read
slave <- ack
master -> uart("addr match\n")
master -> stop
master -> delay(10µs)
// data.
master -> start
master -> dummy byte
slave <- counter_byte
master -> Last=1
slave <- counter++
master -> stop
}


@apollo0226
now you have all.
- opendrain
- ack
- steps in a switch like you thinked
- check for start
- check for stop
- debug prints
- INTR on SDA and SCL
- INTR only SDA with a while on SCL
..

now your homework will be do weekend ( or later )
an i2c slave demo ;-)



i am sure you will do it..
and make a video! :)

go on :)

@martin
Have kept my word
hope this helps
and named me!
"rudi ;-)" is enough
fun

happy second birthday bbs.espressif.com


best wishes
rudi ;-)

Statistics: Posted by rudi — Wed Oct 26, 2016 5:05 am


]]>
2016-10-25T17:04:13+08:00 2016-10-25T17:04:13+08:00 https://bbs.espressif.com:443/viewtopic.php?t=2092&p=10264#p10264 <![CDATA[Documentation Request • Re: I2C Slave Mode]]>

Code:

//Set SDA as open drain
    GPIO_REG_WRITE(
        GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SDA_PIN)),
        GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SDA_PIN))) |
        GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)
    );
    GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_SDA_PIN));
    GPIO_OUTPUT_SET(I2C_SDA_PIN, 1);

    //Set SCK as open drain
    GPIO_REG_WRITE(
        GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SCK_PIN)),
        GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_SCK_PIN))) |
        GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)
    );
    GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_SCK_PIN));
    GPIO_OUTPUT_SET(I2C_SCK_PIN, 1);
   

Statistics: Posted by dkaufmann — Tue Oct 25, 2016 5:04 pm


]]>