Using xxx_periph.h in whole IDF instead of xxx_reg.h, xxx_struct.h, xxx_channel.h ... .
Cleaned up header files from unnecessary headers (releated to soc/... headers).
This MR removes the common dependency from every IDF components to the SOC component.
Currently, in the ``idf_functions.cmake`` script, we include the header path of SOC component by default for all components.
But for better code organization (or maybe also benifits to the compiling speed), we may remove the dependency to SOC components for most components except the driver and kernel related components.
In CMAKE, we have two kinds of header visibilities (set by include path visibility):
(Assume component A --(depends on)--> B, B is the current component)
1. public (``COMPONENT_ADD_INCLUDEDIRS``): means this path is visible to other depending components (A) (visible to A and B)
2. private (``COMPONENT_PRIV_INCLUDEDIRS``): means this path is only visible to source files inside the component (visible to B only)
and we have two kinds of depending ways:
(Assume component A --(depends on)--> B --(depends on)--> C, B is the current component)
1. public (```COMPONENT_REQUIRES```): means B can access to public include path of C. All other components rely on you (A) will also be available for the public headers. (visible to A, B)
2. private (``COMPONENT_PRIV_REQUIRES``): means B can access to public include path of C, but don't propagate this relation to other components (A). (visible to B)
1. remove the common requirement in ``idf_functions.cmake``, this makes the SOC components invisible to all other components by default.
2. if a component (for example, DRIVER) really needs the dependency to SOC, add a private dependency to SOC for it.
3. some other components that don't really depends on the SOC may still meet some errors saying "can't find header soc/...", this is because it's depended component (DRIVER) incorrectly include the header of SOC in its public headers. Moving all this kind of #include into source files, or private headers
4. Fix the include requirements for some file which miss sufficient #include directives. (Previously they include some headers by the long long long header include link)
This is a breaking change. Previous code may depends on the long include chain.
You may need to include the following headers for some files after this commit:
- soc/soc.h
- soc/soc_memory_layout.h
- driver/gpio.h
- esp_sleep.h
The major broken include chain includes:
1. esp_system.h no longer includes esp_sleep.h. The latter includes driver/gpio.h and driver/touch_pad.h.
2. ets_sys.h no longer includes soc/soc.h
3. freertos/portmacro.h no longer includes soc/soc_memory_layout.h
some peripheral headers no longer includes their hw related headers, e.g. rom/gpio.h no longer includes soc/gpio_pins.h and soc/gpio_reg.h
BREAKING CHANGE
GCC compiler can generate 8-bit stores when modifying bitfields of
volatile structs (https://github.com/espressif/esp-idf/issues/597).
In the specific case of I2C driver, this resulted in byte_num field
to be written using s8i. However the peripheral requires 32-bit
writes, and ignores 8-bit writes. This change modifies the code to
compose the 32-bit command register value first, and then write the
complete value to the hardware.
Acquires PM_APB_FREQ_MAX lock when carrying any transaction on I2C if
Power Management Framework is enabled.
Signed-off-by: Sachin Parekh <sachin.parekh@espressif.com>
closes https://github.com/espressif/esp-idf/issues/2494
closes https://github.com/espressif/esp-idf/pull/2493
closes https://github.com/espressif/esp-idf/pull/2496
1. Change bus reset to handle interrupted READ sequences.
2. Slow down I2C to 100khz during reset
3. If a SLAVE device was in a read operation when the bus was interrupted, the SLAVE device is controlling SDA.The only bit during the 9 clock cycles of a byte READ the MASTER(ESP32) is guaranteed control over, is during the ACK bit period.
If the SLAVE is sending a stream of ZERO bytes, it will only release SDA during the ACK bit period. The master(ESP32) cannot generate a STOP unless SDA is HIGH. So, this reset code synchronizes the bit stream with, Either, the ACK bit, Or a 1 bit.
I am stealing this delay coding from @jeremyherbert #2493 pr.
2. Change Bus Reset to handle interrupted READ sequences.
The current code does not handle interrupted READ cycles.
If a SLAVE device was in a read operation when the bus was interrupted, the SLAVE device is controlling SDA.
The only bit during the 9 clock cycles of a byte READ the MASTER(ESP32) is guaranteed control over, is during the ACK bit period.
If the SLAVE is sending a stream of ZERO bytes, it will only release SDA during the ACK bit period. The master(ESP32) cannot generate a STOP unless SDA is HIGH.
So, this reset code synchronizes the bit stream with, Either, the ACK bit, Or a 1 bit.
3. fix typo
correct `sda_id` to `sda_io` in `i2c_master_clear_bus()` @ryan-ma found it. This typo was generated when I manually edited this patch on GitHub, I should have done a Copy/Paste operation!
A couple of typos referencing tx_ring_buf when rx_ring_buf, slv_tx_mux
instead of slv_rx_mux.
Also, I2C_ENTER_CRITICAL()/I2C_EXIT_CRITICAL() usage was not consistent.
Only some of the _set_ functions had them. Most of the _get_ function
had them? It is my understanding that they should be wrapped around
writes, not reads? (I think we still need the lock for reading pairs of consistent values)
Also, the ticks_to_wait timeout handling in i2c_master_cmd_begin() would
not handle integer rollover correctly.
Merges https://github.com/espressif/esp-idf/pull/1180
Reported from github:
https://github.com/espressif/esp-idf/issues/1312https://github.com/espressif/esp-idf/issues/1193
Issues:
1. We used to use event group in the driver, which would cause:
a. longer operation time since the event group are based on FreeRTOS timer.
b. Operation fails if the timer queue is not long enough.
2. There might be some issue with event group, we will still try to provide a small test code in other branch.
modification:
1. use queue instead of event-bit for internal commands
2. use queue overwrite for cmd_done event
Reported from different sources from github or bbs:
https://github.com/espressif/esp-idf/issues/680https://github.com/espressif/esp-idf/issues/922
We tested reading several sensor or other I2C slave devices, if the power and SDA/SCL wires are in proper condition, everything works find with reading the slave.
If we remove the power supply for the slave during I2C is reading, or directly connect SDA or SCL to ground, this would cause the I2C FSM get stuck in wrong state, all we can do is the reset the I2C hardware in this case.
After this commit, no matter whether the power supply of I2C slave is removed or SDA / SCL are shorted to ground, the driver can recover from wrong state.
We are not sure whether this the save issue with the reported one yet, but to make the driver more robust.
Further information:
1. For I2C master mode, we have tested different situations, e.g., to short the SDA/SCL directly to GND/VCC, to short the SDA to SCL, to un-plug the slave device, to power off the slave device. Under all of those situations, this version of driver can recover and keep working.
2. Some slave device will die by accident and keep the SDA in low level, in this case, master should send several clock to make the slave release the bus.
3. Slave mode of ESP32 might also get in wrong state that held the SDA low, in this case, master device could send a stop signal to make esp32 slave release the bus.
Modifications:
1. Disable I2C_MASTER_TRAN_COMP interrupt to void extra interrupt.
2. Disable un-used timeout interrupt for slave.
3. Add bus reset if error detected for master mode.
4. Add bus clear if SDA level is low when error detected.
5. Modify the argument type of i2c_set_pin.
6. add API to set timeout value
7. add parameter check for timing APIs
This issue is reported from https://github.com/espressif/esp-idf/issues/304.
We found that when we operate the hw command registers in I2C struct, sometimes the behaviour would be different in DEBUG/RELEASE optimisation level:
The code looks like this:
I2C[i2c_num]->command[p_i2c->cmd_idx].byte_num -= 0;
In DEBUG configuration:
I2C[i2c_num]->command[p_i2c->cmd_idx].byte_num -= 0;
400f3ab0: 3388 l32i.n a8, a3, 12
400f3ab2: 14c882 addi a8, a8, 20
400f3ab5: a08840 addx4 a8, a8, a4
400f3ab8: 0020c0 memw
400f3abb: 2898 l32i.n a9, a8, 8
400f3abd: 0020c0 memw
400f3ac0: 28b8 l32i.n a11, a8, 8
400f3ac2: 74a090 extui a10, a9, 0, 8
400f3ac5: 00af92 movi a9, 0xffffff00
400f3ac8: 109b90 and a9, a11, a9
400f3acb: 2099a0 or a9, a9, a10
400f3ace: 0020c0 memw
400f3ad1: 2899 s32i.n a9, a8, 8
In RELEASE configuration:
I2C[i2c_num]->command[p_i2c->cmd_idx].byte_num -= 0;
400f2ba2: 580572 l8ui a7, a5, 88
400f2ba5: 747070 extui a7, a7, 0, 8
400f2ba8: 0020c0 memw
400f2bab: 584572 s8i a7, a5, 88
Looks like the compiler will make it a 8bit operation after optimisation.
But the register value changes from 0x901 to 0x101.
After this 8-bit optimisation, the 11th bit changed from 1 to zero, which caused this error.
We are still trying to find out why that happens, because there might be some risk when operating the register struct.
This is a workaround to avoid "-=" operation on I2C register struct fields.
2. update example comments and other minor changes
3. rename API: i2c_cmd_link_create/i2c_cmd_link_delete (+4 squashed commits)
Squashed commits:
[2e0ac3e] 1. coding style: add one space after condition key words.
2. modify i2c.h, use gpio_num_t instead of int, improve comments of return values
3. add i2c index in index.rst
4. add readme for i2c example
[4991d92] update i2c.doc
[88b672e] driver: i2c
1. add mux and spin lock to run in a thread-safe way.
2. modify example code
[4eb15fe] driver: i2c code
1. add i2c master code
2. add i2c slave code
3. add i2c example code
4. add DRAM_ATTR for I2C array