Compare commits

...

353 Commits

Author SHA1 Message Date
286202caa3 Merge branch 'bugfix/mqtt_fragmented_packed_msg_3.2' into 'release/v3.2'
MQTT support for fragmented and packed messages (Backport 3.2)

See merge request idf/esp-idf!4593
2019-03-25 10:49:56 +08:00
9ebaf36c28 tcp_transport: modification of ws to read headers first in order to read the exact payload
closes https://github.com/espressif/esp-mqtt/issues/69
2019-03-21 14:35:59 +01:00
1ece141c52 mqtt: support for BEFORE_CONNECT event in idf
Updated examples to use new event id, idf to use mqtt with fixed retained, oversized messages
2019-03-21 14:35:49 +01:00
f49e2afe94 Merge branch 'bugfix/sphinx_build_failure_on_rtd_v3.2' into 'release/v3.2'
docs: Upgraded sphinx package version to prevent build failures on readthedocs…

See merge request idf/esp-idf!4554
2019-03-21 14:24:24 +08:00
17b260d05c Merge branch 'bugfix/nvs_api_usage_in_simple_ota_example_v3.2' into 'release/v3.2'
Minor bugfix in simple ota example (backport v3.2)

See merge request idf/esp-idf!4584
2019-03-21 13:06:48 +08:00
07fc1d181f bugfix(simple_ota): Compatible with V3.1 and V3.2
(cherry picked from commit 0fa31d3e31)
2019-03-21 10:24:09 +08:00
beb29bc88a Merge branch 'bugfix/btdm_fix_no_adv_report_when_scaning_with_sleep_enable_v3.2' into 'release/v3.2'
Component/bt: fix no adv report when scanning with sleep enable(backport v3.2)

See merge request idf/esp-idf!4537
2019-03-20 22:03:12 +08:00
ccc1263ca8 docs: Upgraded sphinx package version to prevent build failures on readthedocs site. Upgraded versions of other packages that are used during documentation build. (backport v3.2) 2019-03-19 20:22:07 +01:00
d6bdaed141 Component/bt: fix no adv report when scanning with sleep enable 2019-03-18 17:40:19 +08:00
13018449fe Merge branch 'bugfix/remove_malloc_ble_prov_v3.2' into 'release/v3.2'
(backport v3.2) Protocomm BLE: Make changes in handling BLE read/write requests

See merge request idf/esp-idf!4495
2019-03-15 14:29:30 +08:00
b6687e56ed Merge branch 'bugfix/console_allow_buffered_v3.2' into 'release/v3.2'
console example: use buffered stdout by default (backport v3.2)

See merge request idf/esp-idf!4507
2019-03-15 14:03:29 +08:00
6494927766 examples: don't enable buffering on stdout in console examples
newlib uses significantly more stack space when printing to an
unbuffered stream. To reduce the amount of stack space required to
use the console, don’t disable buffering. linenoise should support
unbuffered stdout instead.
2019-03-15 11:29:56 +08:00
6ce5c7668f console/linenoise: support buffered stdout 2019-03-15 11:29:56 +08:00
c97a05c0d5 Merge branch 'feature/btdm_add_update_duplicate_scan_exceptional_list_apis_v3.2' into 'release/v3.2'
Component/bt: add update duplicate scan exceptional list APIs

See merge request idf/esp-idf!4494
2019-03-15 10:46:57 +08:00
fed772641a Component/bt: add update duplicate scan exceptional list APIs 2019-03-14 20:59:38 +08:00
39d8a89c80 Protocomm BLE: Make changes in handling BLE read/write requests
1. Remove unwanted malloc during BLE send response
2. Populate the missing parameters in the response - handle, offset, auth_req
2019-03-14 12:50:03 +05:30
62980ae995 Merge branch 'feature/btdm_add_adv_report_flow_control_v3.2' into 'release/v3.2'
component/bt: add vendor hci and adv report flow control (backport v3.2)

See merge request idf/esp-idf!4462
2019-03-14 13:51:52 +08:00
029a155a71 Merge branch 'bugfix/mdns_add_remove_multiple_srv_3.2' into 'release/v3.2'
mdns: fix possible crash if tx packet contained answer to removed service (backport 3.2)

See merge request idf/esp-idf!4481
2019-03-14 07:56:40 +08:00
4849d7ae90 Merge branch 'bugfix/mdns_incorrect_semaphore_use_v3.2' into 'release/v3.2'
mdns: use binary semaphore instead of mutex when searching (Backport 3.2)

See merge request idf/esp-idf!4478
2019-03-14 06:26:51 +08:00
10b4ddb467 mdns: fix possible crash when probing on particular interface with duplicated service instances due to naming conflicts on network
Issue: MDNS server initially sends probing packets to resolve naming confilicts with already registered service instances. In case of a conflict, instance name is altered and probing restarts. Original instance however wasnnot removed from the structure and upon service removal only one entry was removed and a dangling service might have been kept in the structure to bring about a crash.
Resolution: Keep only one instance of a service in the probing structure.

Closes IDF-438
2019-03-13 16:24:18 +01:00
288bc2bfca mdns: enable pcbs before starting service thread to avoid updating pcb's internal variables from concurent tasks
possible race condition: user task runs mdns_init, which enables pcbs while mdns-task already created could execute enable/disable of the same pcbs if an appropriate system event received
2019-03-13 16:24:03 +01:00
8e4ec90dc4 mdns: fix possible deadlock on mdns deinit calling mdns_free()
mnds_free() initiates stop and delete timer tasks, which after locking the mutex could lead to a dead lock in case timer task executed before deleting the task, as it would wait indefinitelly for unlocking the mutex. This condition is fixed by calling _mdns_stop_timer without locking the mutex, because there's no need to protect any data when stopping and deleting the timer task

Closes https://github.com/espressif/esp-idf/issues/1696
2019-03-13 16:24:03 +01:00
0e06b4d653 mdsn: fix race condition in updating packet data from user task when failed to allocate or queue a new service
Issue: mdns_service_add API allocates and queues an action to be processed in mdns task context; when allocation or queueing fails, allocated structure needs to be freed. Function _mdns_free_service did not only fee all the structures, but also updates packet data.
Resolution: Moved removal of packet data outside of _mdns_free_service function.
2019-03-13 16:24:03 +01:00
8fe4007dfa mdns: fix possible crash when packet scheduled to transmit contained service which might have been already removed
packets scheduled to transmit are pushed to action queue and removed from tx_queue_head structure, which is searched for all remaining services and while service is removed, then service questions/asnwers are also removed from this structure. This update fixes possible crash when packet is pushed to action queue, and when service is removed, its answers are removed from tx_queue_head, but not from action queue. this could lead to a crash when the packet is poped from action queue containing questions/answers to already removed (freed) service

Closes IDF-438
2019-03-13 16:24:03 +01:00
09f4015300 mdns: use binary semaphore instead of mutex when searching
mdns_search_once_t::lock is used to synchronize tasks (taken by one
task and given by the other) so it should not be a mutex.
Convert to semaphore, and rename to indicate its purpose.
2019-03-13 14:55:01 +01:00
56918682f9 Merge branch 'bugfix/confgen_expr_value_v3.2' into 'release/v3.2'
confgen: Fix bug with JSON metadata conditional range generation

See merge request idf/esp-idf!4470
2019-03-13 16:54:41 +08:00
6b49a355f7 confgen: Fix bug with JSON metadata conditional range generation
When generating JSON metadata for ranges where there are conditional ranges (ie different allowed range
depending on another config setting), the JSON metadata would always have the last named range as
the expression was not evaluated properly.

Thanks to ulfalizer on GitHub for pointing this out.

Closes https://github.com/espressif/esp-idf/issues/2195
2019-03-13 16:50:55 +11:00
6628fddae6 Component/bt: add BLE adv report flow control 2019-03-12 20:18:30 +08:00
ff99e0ea69 Merge branch 'feature/upgrade_sphinx_and_breathe_v3.2' into 'release/v3.2'
docs: Preparation for upgrade of Sphinx and Breathe packages to versions 1.8.4…

See merge request idf/esp-idf!4380
2019-03-12 16:53:11 +08:00
zwj
b305a96a74 component/bt: add vendor hci cmd 2019-03-12 11:55:42 +08:00
12643e063c Merge branch 'bugfix/autoip_memoey_leak_debug_v3.2' into 'release/v3.2'
fix the bug in auto Ip memory leak (backport v3.2)

See merge request idf/esp-idf!4431
2019-03-08 19:54:34 +08:00
a7dc804476 Merge branch 'bugfix/httpd_sess_ctx_backportv3.2' into 'release/v3.2'
esp_http_server: Provide apps an option to let http_server ignore sess_ctx changes

See merge request idf/esp-idf!4421
2019-03-08 11:52:17 +08:00
8e0b0af09b fix the bug in auto Ip memory leak 2019-03-06 20:01:36 +08:00
e1e82c8949 Merge branch 'bugfix/lack_of_break_in_tcp_client_v3.2' into 'release/v3.2'
fix the bug in tcp_client (backport v3.2)

See merge request idf/esp-idf!4391
2019-03-06 14:22:59 +08:00
d99d92e170 Merge branch 'bugfix/fix_dig_gpio_unable_hold_bug_v3.2' into 'release/v3.2'
Bugfix/fix digital gpio unable hold bug  (backport v3.2)

See merge request idf/esp-idf!4355
2019-03-06 12:10:38 +08:00
f8f0c81077 esp_http_server: Provide apps an option to let http_server ignore sess_ctx changes
By default, if a URI handler changes the http session context,
the webserver internally clears the older context after the handler
returns. However, if applications want to change this behavior and
manage the allocation/de-allocation/freeing themselves and let the
server handle only the "socket close" case, this commit provides such
an option.
2019-03-05 13:06:33 +05:30
727c2cfa00 Merge branch 'feature/add_api_get_rmt_idle_level_v3.2' into 'release/v3.2'
Bugfix:  Fixed some RMT related issues (backport v3.2)

See merge request idf/esp-idf!4358
2019-03-05 10:51:00 +08:00
e9a764d9a5 Merge branch 'bugfix/make_get_coreid_volatile_backport_v3.2' into 'release/v3.2'
freertos: Make xPortGetCoreID() volatile (backport v3.2)

See merge request idf/esp-idf!4379
2019-03-01 18:49:00 +08:00
b2e4af4ed0 Merge branch 'bugfix/ble_reconn_rescan_readv_crash_v3.2' into 'release/v3.2'
component/bt : fix bug that there's low ratio crash when BLE do re-connect/re-scan/re-adv

See merge request idf/esp-idf!4325
2019-03-01 18:06:02 +08:00
66a0b64e54 freertos: Make xPortGetCoreID() volatile
When xPortGetCoreID() is called twice within a function,
it might only be called once after compilation. This
commit makes the inline assembly of the function volatile.

Closes #3093
2019-03-01 02:05:33 +00:00
9d48cdb6f3 Merge branch 'bugfix/multiple_backports_v3.2' into 'release/v3.2'
multiple backports (v3.2)

See merge request idf/esp-idf!4367
2019-02-28 21:42:19 +08:00
258e9c98be Merge branch 'bugfix/cmake_psram_fix_flag_v3.2' into 'release/v3.2'
cmake: Fix psram workaround compiler flag application (backport v3.2)

See merge request idf/esp-idf!4364
2019-02-28 21:06:11 +08:00
35e491856e ci: Only use "github_sync" tagged runners to talk to GitHub 2019-02-28 20:38:31 +08:00
226c790766 ci: Retry submodule sync 2 more times before failing 2019-02-28 20:38:31 +08:00
c0d32f6e48 nvs: add a blob fragmentation test case
Ref. TW12937
2019-02-28 20:38:31 +08:00
203f75223e nvs: do eager cleanup of HashListBlocks
Previously when HashList was removing items, HashListBlocks were
removed lazily. This resulted in empty HashListBlocks dangling around
in full pages, even when all items have been erased. These blocks
would only be deleted when NVS was re-initialized
(nvs_flash_deinit/nvs_flash_init).

This change does eager cleanup instead, based on the code from
@negativekelvin offered in
https://github.com/espressif/esp-idf/issues/1642#issuecomment-367227994.

Closes https://github.com/espressif/esp-idf/issues/1642.
2019-02-28 20:38:31 +08:00
742f8e7f8a esp_timer: fix occasional failures in "monotonic values" test
1. ref_clock used in unit tests occasionally produces time off by ~100
microseconds shortly after being started. Add a delay to let
ref_clock stabilise, until the cause is found.

2. Reduce roundoff error accumulation which would occasionally cause
the test to fail, by choosing an overflow value which can be divided
by APB frequency.

3. Move time sampling part of the test into an IRAM function to
reduce variations due to cache behavior.

4. Remove calculation of "standard deviation" in the test, as what was
calculated was not actually standard deviation, and it did not add any
useful information.
2019-02-28 20:38:31 +08:00
7e16a79cf7 esp_timer: improve unit test robustness
1. call esp_timer_get_time and ref_clock_get in the same order on
   start and in the loop

2. disable interrupts when calculating delta between ref_clock
   and esp_timer

3. ensure both functions are in cache before calculating the delta
2019-02-28 20:38:31 +08:00
22dc4898d9 soc: define named constants for DPORT_CPUPERIOD_SEL values 2019-02-28 20:38:31 +08:00
f78c96a3d7 bootloader: check previously used clock frequency at run time
In the situation when bootloader was compiled for 240MHz, and app was
compiled for 160MHz, and the chip is a revision 0 chip, the
bootloader will assume that the application has also been running at
240MHz. This will cause the chip to lock up later. Modify this to use
a run time check of DPORT_CPUPERIOD_SEL, which indicates which of the
PLL frequencies was used.

Closes https://github.com/espressif/esp-idf/issues/2731.
2019-02-28 20:38:31 +08:00
b4727a8765 soc/rtc_clk: don’t clear DPORT_CPUPERIOD_SEL when switching to XTAL
This is not necessary since RTC_CNTL_SOC_CLK_SEL is set before this.
2019-02-28 20:38:31 +08:00
8bbd99ad9e make: fix issues related to EXTRA_COMPONENT_DIRS
1. When one of the COMPONENT_DIRS points to a component directory
(i.e. a directory containing component.mk, not a directory of multiple
components), and there is a subdirectory in it which also contains
a component, the subdirectory was mistakenly added to the list of
components and compiled.

For example:

    main/
        component.mk
        main.c
        test/
            component.mk
            test_main.c

Would compile test_main.c and link libtest.a.

2. When one of the COMPONENT_DIRS points to a component directory, and
the parent directory contained a directory with the same name as
another component, that directory would be mistakenly added to the
COMPONENT_PATHS.

For example:

    esp/
        esp-idf/
        esp32/
            (random stuff)
        mycomponent/
            component.mk
            mycomponent.c
        myproject/
            main/
            Makefile

and Makefile sets EXTRA_COMPONENT_DIRS=$(realpath ../mycomponent),
then "esp32" directory which is at the same level as mycomponent
was added to COMPONENT_PATHS.

3. If EXTRA_COMPONENT_DIRS pointed to a directory with a list of
components, and one of the subdirectories was not a component, but
had the same name as another component, than that directory would be
mistakenly added to COMPONENT_PATHS instead of the real esp32
component directory.

For example:

    my_components/
        my_component/
            component.mk
            my_component.c
        esp32/
            (some random stuff)

and EXTRA_COMPONENT_DIRS would point to my_components/, then "esp32"
directory would be added to COMPONENT_PATHS instead of the real esp32
component directory.
2019-02-28 20:38:31 +08:00
5dcdef0639 kconfig: fix compatibility with very old versions of flex
See 4e762e4918

Closes https://github.com/espressif/esp-idf/issues/2703
2019-02-28 20:38:31 +08:00
d651ee3d28 fix the bug in tcp_client
Closes https://github.com/espressif/esp-idf/issues/3058
2019-02-28 14:25:54 +08:00
83d7b4591c Merge branch 'esp_http_server/lru_counter_for_timestamp_backportv3.2' into 'release/v3.2'
esp_http_server/lru_counter_for_timestamp:Added LRU counter for timer(backport v3.2)

See merge request idf/esp-idf!4319
2019-02-28 07:03:38 +08:00
f5096892f9 docs: Preparation for upgrade of Sphinx and Breathe packages to versions 1.8.4 and 4.11.1. Updated check of Sphinx warnings to account for the filename instead of the whole path, that for the same errors may be different between English and Chinese docs. (backport v3.2) 2019-02-27 23:21:47 +01:00
56694fb4b6 cmake: Fix psram workaround compiler flag application
Previously, this compiler flag was not being applied
regardless of CONFIG_SPIRAM_CACHE_WORKAROUND setting.

Explanation: add_compile_options() only applies to
source files added after the function is run, or in
subdirectories added after the function is run. In
this case, no new source files were being added after
this function was run.
2019-02-27 16:38:29 +11:00
929542d4fa driver(rmt): Fixed some RMT related issues.
1. Add missing get function to RMT API: rmt_get_idle_level().
2. Suppress error message from rmt_wait_tx_done() if wait_time==0 (allows for polling).
3. Remove the blank lines between parameter lists.

Merges https://github.com/espressif/esp-idf/pull/2666
2019-02-26 20:46:23 +08:00
be49c8d841 driver(gpio): fixed digital gpio unable hold bug during deep-sleep for release/v3.2. 2019-02-26 20:20:25 +08:00
67aefe1011 component/bt : fix bug that there's low ratio crash when BLE do re-connect/re-scan/re-adv
fix 3 bugs:
1. do BLE connect (both of slave and master), it mgiht cause crash due to there's much interrupts happens effect ble code running, for example, wifi run on the same core as bluetooth controller and wifi run throughtput test.
2. do BLE scan stop or adv stop or connection stop, it might cause ASSERT or crash due to memory corrupted in controller memory poll.
3. minor bug fix, not really effect bluetooth.
2019-02-25 13:40:46 +00:00
58e49d169c esp_http_server/lru_counter_for_timestamp:Added LRU counter for timer
Replaced the os timer in http server by LRU counter. The timestamp is
unnecessary for LRU.
2019-02-25 09:16:28 +00:00
a241f95407 Merge branch 'bugfix/freertos_unused_xSize_backport_v3.2' into 'release/v3.2'
freertos: Fix unused variable warning (backport v3.2)

See merge request idf/esp-idf!4296
2019-02-25 15:44:22 +08:00
aaaa491c42 freertos: Fix unused variable warning
This commit fixes an unused variable warning when
configASSERT is undefined.
2019-02-22 01:06:44 +08:00
91aa35e831 Merge branch 'bugfix/mdns_service_memory_leak_3.2' into 'release/v3.2'
mdns: fix memory leak when query for service plus various other fixes (Backport v3.2)

See merge request idf/esp-idf!4287
2019-02-21 17:53:32 +08:00
113e829552 mdns: fix memory leak in pbuf if tcpipadapter failed to get netif 2019-02-21 06:43:23 +00:00
3802fddefb mdns example: fix print result for IPv6 addresses 2019-02-21 06:43:23 +00:00
bb2eb9adeb mdns: fix malfuctional query_txt
when running a query for a single txt, result entries were not created and attached to result structure. this issue was introduced when fixing memory leak in txt structure, which worked correctly for PTR queries, but caused trouble for TXT query.
2019-02-21 06:43:23 +00:00
78116afa01 mdns: fix possible crash when mdns_free called while action queue not empty 2019-02-21 06:43:23 +00:00
b865e72aec mdns: fix memory leak when query for service receives multiple ptr entries for one instance
fixes redmine issue 27300
2019-02-21 06:43:23 +00:00
f1b2457b6c Merge branch 'bugfix/psram_move_qsort_setlocale_flash_v3.2' into 'release/v3.2'
psram: Move newlib qsort() and setlocale() functions from IRAM to flash (backport v3.2)

See merge request idf/esp-idf!4322
2019-02-21 14:42:17 +08:00
46fa5654a7 Merge branch 'bugfix/btdm_fix_connection_params_update_issues_v3.2' into 'release/v3.2'
component/bt:fix connection params update issues (backport v3.2)

See merge request idf/esp-idf!4297
2019-02-21 11:49:16 +08:00
bf28a1a27b psram: Move newlib qsort() and setlocale() functions from IRAM to flash 2019-02-21 10:32:00 +11:00
b7beefba9e Merge branch 'bugfix/cmake_stack_protector_v3.2' into 'release/v3.2'
esp32: disable stack protector for startup code (CMake) (backport v3.2)

See merge request idf/esp-idf!4250
2019-02-20 15:40:14 +08:00
0784c52131 Merge branch 'doc/add_coap_readme' into 'release/v3.2'
doc: add CoAP README.md(backport v3.2)

See merge request idf/esp-idf!4262
2019-02-20 15:38:43 +08:00
a7f826750b Merge branch 'revert-00d10688' into 'release/v3.2'
Revert "Merge branch 'bugfix/external_rtc_start_fail_3.2' into 'release/v3.2'"

See merge request idf/esp-idf!4293
2019-02-20 15:09:59 +08:00
38086ae737 Merge branch 'bugfix/spiram_linker_wildcards_v3.2' into 'release/v3.2'
esp32 psram: Provide library name for ROM libc objects linked as PSRAM workarounds (backport v3.2)

See merge request idf/esp-idf!4153
2019-02-20 14:17:52 +08:00
6173660ff0 Merge branch 'bugfix/coex_lc_protect_v3.2' into 'release/v3.2'
component/esp32 : fix coexist lc protect cause memory corrupted

See merge request idf/esp-idf!4267
2019-02-20 11:14:22 +08:00
79b450cfb4 esp32 psram: Provide library name for ROM libc objects linked as PSRAM workarounds
Fixes bug reported on forums where any source file ending in *lock.c or *creat.c
was being linked to IRAM.

https://esp32.com/viewtopic.php?f=13&t=8909&p=37362#p37362
2019-02-20 00:30:25 +00:00
c7fbc6dd85 Merge branch 'bugfix/wdt_compability_app_with_old_bootloader_v3.2' into 'release/v3.2'
esp32: Fix wdt settings in esp_restart_noos (backport v3.2)

See merge request idf/esp-idf!4294
2019-02-20 02:17:09 +08:00
3b5bba1812 Merge branch 'bugfix/fix_psram_eid_v3.2' into 'release/v3.2'
bugfix(psram): fix psram size acquisition method, support esp32-pico chips (backport v3.2)

See merge request idf/esp-idf!4254
2019-02-20 02:13:47 +08:00
zwj
b4feb67b5f component/bt:fix connection params update issues 2019-02-19 20:26:36 +08:00
578d7902af Merge branch 'bugfix/btdm_crash_when_inquiry_cancel_v3.2' into 'release/v3.2'
Bugfix/btdm crash when inquiry cancel v3.2

See merge request idf/esp-idf!4277
2019-02-19 17:57:00 +08:00
509884c5ac Revert "Merge branch 'bugfix/external_rtc_start_fail_3.2' into 'release/v3.2'"
This reverts merge request !4272
2019-02-19 12:47:44 +08:00
8a656f006e esp32: Fix wdt settings in esp_restart_noos
Fixed compatibility the new apps with the old bootloaders.

Closes: https://github.com/espressif/esp-idf/issues/2927
2019-02-19 12:43:35 +08:00
0f79c72704 Merge branch 'bugfix/aws_iot_backport_few_fixes_for_v3.2' into 'release/v3.2'
Bugfix/aws iot backport few fixes for v3.2 (backport_v3.2)

See merge request idf/esp-idf!4247
2019-02-19 11:36:18 +08:00
6d6f71bbae component/esp32 : fix coexist lc protect cause memory corrupted
The bug will cause memory corrupted (the largest range is from 0x3ffc0000 ~ 0x3ffc8000),
some strange error will happen, like IllegalInstruction, LoadProhibited and .etc.
2019-02-19 03:30:02 +00:00
332ccd0925 Merge branch 'feature/provisioning_backport_api_changes' into 'release/v3.2'
(backport v3.2)  Provisioning Framework API changes

See merge request idf/esp-idf!4249
2019-02-19 10:47:47 +08:00
2ee1c6fd3e provisioning examples : typos fixed and minor change in timer callback execution
Note : Examples have been updated to prevent invocation of bluedroid/wifi APIs from inside timer callback when stopping provisioning. Workaround is to spawn new task from inside the timer callback.
2019-02-18 08:18:44 +00:00
6a328992d7 protocomm : typos fixed and descriptions corrected 2019-02-18 08:18:44 +00:00
b51f109dd7 protocomm unit_tests : test cases updated
Changes:
* Version endpoint test added
* Memory leak test updated to include corner case exceptions in protocomm
2019-02-18 08:18:44 +00:00
85e8dea26a protocomm security : memory leaks fixed
List of changes:
* Corner case exceptions are properly handled to ensure release of memory occupied by security infrastructure
* fixed erroneous cleanup of security instance by protocomm_console
2019-02-18 08:18:44 +00:00
093c7b176d protocomm : version endpoint behavior simplified
List of changes:
* Version endpoint now sends the set version string instead of verifying the incoming version string. This simplifies fetching version info from the provisioning application.
* esp_prov script updated to expect version string as response.
2019-02-18 08:18:44 +00:00
30e39631db wifi_provisioning : context pointer added to wifi_config_t structure and related examples/docs updated
Closes https://github.com/espressif/esp-idf/issues/2874
2019-02-18 08:18:44 +00:00
a7ff611b10 provisioning framework : 'extern C' directives added for C++ support 2019-02-18 08:18:44 +00:00
2e64d2d56e softap_prov: Changes in the example code as per changes to protocomm_httpd
Signed-off-by: Piyush Shah <piyush@espressif.com>
2019-02-18 08:18:44 +00:00
3e6b402756 protocomm_httpd: Allow applications to pass HTTPD handle
This will be useful if a webserver is already running and the application
does not want protocomm to start a new instance.

Signed-off-by: Piyush Shah <piyush@espressif.com>
2019-02-18 08:18:44 +00:00
5568ca2855 components/bt: Add precautions for esp_vhci_host_send_packet (backport 3.2) 2019-02-18 08:15:17 +00:00
30f2371917 components/bt: Fix crash when inquiry stop (backport v3.2) 2019-02-18 08:15:17 +00:00
ebaa944a9a Merge branch 'test/disable_sdio_example_ci_v3.2' into 'release/v3.2'
sdio: temporarily disable the sdio example ci

See merge request idf/esp-idf!4284
2019-02-18 16:14:01 +08:00
d83598a64a sdio: temporarily disable the sdio example ci, since the runners have
some power issue
2019-02-18 11:02:43 +08:00
00d1068869 Merge branch 'bugfix/external_rtc_start_fail_3.2' into 'release/v3.2'
Bugfix/external rtc start fail (backport 3.2)

See merge request idf/esp-idf!4272
2019-02-15 17:51:49 +08:00
49be9fb836 doc: add CoAP README.md 2019-02-15 16:03:54 +08:00
6f0c70daf6 Merge branch 'bugfix/bugfix/mdns_notask_timer_crash_v3.2' into 'release/v3.2'
mdns: fix crash after init if no memory for task (Backport 3.2)

See merge request idf/esp-idf!4237
2019-02-15 13:49:29 +08:00
219c85cf60 Merge branch 'bugfix/btdm_allow_a2dp_codec_dynamic_allocated_for_v3.2' into 'release/v3.2'
bugfix/btdm_allow_a2dp_codec_dynamic_allocated_for_v3.2(backport v3.2)

See merge request idf/esp-idf!4260
2019-02-15 13:42:39 +08:00
524696d59a Merge branch 'bugfix/fix_some_wifi_bugs_0131_v3.2' into 'release/v3.2'
esp32: fix some WiFi bugs (backport v3.2)

See merge request idf/esp-idf!4217
2019-02-15 12:14:54 +08:00
9a229f4077 soc/rtc: fix RTC_TOUCH_TRIG_EN or RTC_ULP_TRIG_EN should keep RTC_PERIPH power on 2019-02-15 10:58:14 +08:00
016c8d8b05 soc/rtc: Bypass touchpad current to external 32k crystal oscillator 2019-02-15 10:55:08 +08:00
9914b839aa Merge branch 'update/nvs_partition_utility_v3.2' into 'release/v3.2'
Update/nvs partition utility v3.2 (backport v3.2)

See merge request idf/esp-idf!4258
2019-02-15 08:51:17 +08:00
76e4ea7f68 nvs_util: Fix to support write of multiple singlepage big blob data
Closes https://github.com/espressif/esp-idf/issues/3011

(cherry picked from commit ce4944edf01b2a4c997eafe36b66d71f98f2fe29)
2019-02-14 18:05:59 +05:30
3ec0f415a5 nvs_util: Fix to support write of multiple singlepage big blob data Closes https://github.com/espressif/esp-idf/issues/3011
(cherry picked from commit 21688e3bffee80ddfbef5364a44dd1821e28c776)
2019-02-14 15:57:23 +05:30
fa40b3d5d0 Update minimum version for cryptography package required
(cherry picked from commit e1774cb6f9)
2019-02-13 17:20:01 +05:30
f742808333 nvs_util: update test case
(cherry picked from commit 0c72b08872)
2019-02-13 17:12:57 +05:30
51bd64c754 Update README
(cherry picked from commit 582c547191)
2019-02-13 17:12:50 +05:30
b85321be97 Closes https://github.com/espressif/esp-idf/issues/2472
(cherry picked from commit c44f15441f)
2019-02-13 17:12:40 +05:30
dcd63f73f6 nvs_util: Add changes to nvs part gen util
nvs_util: Add changes to nvs part gen util

nvs_host_test: Add test case for keygen and keyfile paratmeters

(cherry picked from commit 9db1987892)
2019-02-13 17:11:59 +05:30
b8f0c32a0a component/bt: allow dynamic allocation of SBC encoder/decoder buffer used in A2DP to save internal DRAM 2019-02-13 19:15:34 +08:00
8f2e1471af bugfix(psram): made some modifcations to support the psram driver backport 2019-02-13 16:06:38 +08:00
a159e58ead feature(psram): add psram support for esp32-pico chip
1. esp32-pico use standard spi driver to access psram
2. for esp32-pico, flash and psram share the clock
3. for esp32-pico, psram cs io can be overwrite via menuconfig
2019-02-13 14:27:44 +08:00
fe767855df bugfix(psram): fix psram size acquisition method
1. Use BIT[7:5] of EID to determine psram size
2. Add ID support for 16Mbit psram
3. Remove module reset on SPI1
4. Confirmed with the vendor that only the old 32Mbit psram need special clock timing. For other psram chips, we should use standard QPI mode.
2019-02-13 14:24:20 +08:00
1e674fb4ed esp32: disable stack protector for startup code (CMake)
Files where stack protector is initialized should not be compiled with
stack protector enabled. This was done for Make but missing for CMake.

Fixes https://github.com/espressif/esp-idf/issues/2990.
2019-02-13 10:27:22 +08:00
3660ccac4c Merge branch 'bugfix/esp-http-client-fixes' into 'release/v3.2'
Minor Bugfixes in esp_http_client, tcp_transport and simple_ota_example. (backport v3.2)

See merge request idf/esp-idf!4248
2019-02-13 07:10:34 +08:00
4f9a4e8ed7 examples/simple_ota_example: Fix incorrect component reference in README 2019-02-12 11:32:54 +05:30
582bf18789 tcp_transport: Fix incorrect error logging in ssl_read and ssl_write APIs
Closes https://github.com/espressif/esp-idf/issues/2805
2019-02-12 11:32:44 +05:30
2e3f06ece8 esp_http_client: Fix for setting incorrect post header length
Closes https://github.com/espressif/esp-idf/issues/2638
2019-02-12 11:32:23 +05:30
c62a20f162 ci: remove IDF_CI_BUILD variable, no active users 2019-02-12 11:03:40 +05:30
ed4d83af8e examples: aws_iot: fix cmake build issue which used to pick dummy certificates
For CI build now `sdkconfig.ci` file is used which builds examples assuming certificate
stored on SDCard.
2019-02-12 11:03:14 +05:30
1444868917 Merge branch 'bugfix/eth_gpio0_output_v3.2' into 'release/v3.2'
ethernet cleanup && support GPIO0 output mode && support IP101(backport v3.2)

See merge request idf/esp-idf!4214
2019-02-12 07:54:57 +08:00
05ba4f15d6 examples: update default root-ca for aws_iot demos 2019-02-08 18:54:01 +05:30
37b7153c0e Merge branch 'feature/http_server_backport_api_changes' into 'release/v3.2'
(backport v3.2) HTTP Server API changes

See merge request idf/esp-idf!4232
2019-02-08 11:43:33 +08:00
1a53334843 mdns: fix crash after init if no memory for task
mdns init first starts timer task, then starts service task. if service task failed to be created, timer task needs to be stopped too.
fixed https://ezredmine.espressif.cn:8765/issues/28466
2019-02-05 07:59:38 +01:00
fd29b0165f Merge branch 'bugfix/event_loop_library_memory_leak_v3.2' into 'release/v3.2'
Fix event loop library memory leak (backport v3.2)

See merge request idf/esp-idf!4221
2019-02-04 16:35:17 +08:00
9c3262f80b esp_http_server : APIs renamed and context get/set implementations fixed
* http_sess_set_*_override APIs are now the only ones available to set custom recv/send/pending functions
* Fixed side effects to using http_sess_set/get_context inside URI handlers
2019-02-03 21:50:35 +05:30
900dbfd1f6 esp_http_server example tests : updated advanced_tests as per API changes 2019-02-03 21:32:21 +05:30
13a1f4ed78 esp_http_server improvements to allow adding transport layer encryption
Changes:
- renamed `httpd_free_sess_ctx_fn_t` to `httpd_free_ctx_fn_t`
- added a `httpd_handle_t` argument to `httpd_send_func_t` and `httpd_recv_func_t`
- internal function `httpd_sess_get()` is no longer static, as it's used in other
  files besides httpd_sess.c

Bug fixes:
- removed a trailing semicolon from `HTTPD_DEFAULT_CONFIG()`
- fixed issue with failed `select()`, now it automatically closes invalid sockets
  instead of shutting down the entire server

New features:
- `httpd_resp_send()` and `httpd_resp_send_chunk()` now accept -1 as length to use
  `strlen()` internally
- added `httpd_sess_set_ctx()` to accompany `httpd_sess_get_ctx()`
- added a "transport context" to the session structure (next to user context)
- added `httpd_sess_{get,set}_transport_ctx()` to work with this transport context
- added "global user context" and "global transport context" stored in the server
  config (and then the handle); supports a user-provided free_fn
- added a "pending func" to e.g. check for data in the transport layer receive
  buffer
- added functions `httpd_set_sess_{send,recv,pending}_override()` that target
  a session by ID (i.e. not using a request object)
- added `httpd_set_pending_override()`
- added a "open_fn" and "close_fn" - functions called when creating and closing
  a session. These may be used to set up transport layer encryption or some other
  session-wide feature
2019-02-03 21:32:07 +05:30
8a69ffc36f Merge branch 'bugfix/btdm_add_handle_in_gatts_conf_event_for_indication_v3.2' into 'release/v3.2'
Component/bt: add handle in gatts conf event for indication (backport v3.2)

See merge request idf/esp-idf!4222
2019-02-01 21:34:05 +08:00
a437e4dc5c Merge branch 'bugfix/btdm_fix_write_char_crash_after_disconnection_v3.2' into 'release/v3.2'
Component/bt: fix write char crash after disconnection (backport v3.2)

See merge request idf/esp-idf!4210
2019-02-01 21:28:29 +08:00
741f97da4e esp32: fix some WiFi bugs
Fix following WiFi bugs:
1. Fix a crash bug which is caused by WiFi static TX buffer alloc/free.
2. Fix the bug that iphone fails to connect to ESP32 AP by enabling AP BAR receiving.
3. Fix the bug that ESP32 station fails to connect some APs, such as Xiaomi hotspot etc,
   after reset.
2019-02-01 11:52:40 +08:00
eae2baa0f1 esp_event: detect leaks in unit test 2019-02-01 10:08:50 +08:00
f49f5ff35a esp_event: fix post data type inconsistency 2019-02-01 10:08:50 +08:00
020b295f06 esp_event: fix memory leaks
Closes https://github.com/espressif/esp-idf/issues/2886
2019-02-01 10:08:50 +08:00
6e14de0fa8 Merge branch 'mesh/malloc_routing_table_v3.2' into 'release/v3.2'
mesh: modify to malloc routing table (backport v3.2)

See merge request idf/esp-idf!4178
2019-02-01 10:02:24 +08:00
95c7f45e84 Component/bt: add handle in gatts conf event for indication 2019-01-31 20:30:23 +08:00
651a08f710 Component/bt: fix write char crash after disconnection 2019-01-31 12:20:16 +00:00
18cb87b4ce ethernet: support new PHY (IP101)
1. Add support for new PHY IP101.
2. Re-enable GPIO0 output mode.
3. Clean up some docs.
2019-01-31 15:02:45 +08:00
1fedece94d Merge branch 'feature/add_ipv6_related_change_v3.2' into 'release/v3.2'
modify test case to support ipv6 (backport v3.2)

See merge request idf/esp-idf!4074
2019-01-31 14:31:44 +08:00
137810915c mesh: modify to malloc routing table 2019-01-31 13:46:50 +08:00
bb766355b5 Merge branch 'bugfix/tw28445_wps_thread_safe_v3.2' into 'release/v3.2'
esp32: fix WPS thread-safe (backport v3.2)

See merge request idf/esp-idf!4195
2019-01-30 17:50:33 +08:00
807ef53c38 Merge branch 'bugfix/mdns_crash_free_strdup_3.2_fix' into 'release/v3.2'
mdns: fixed crash on free undefined ptr if strdup is skipped (Backport 3.2 FIX)

See merge request idf/esp-idf!4197
2019-01-30 14:24:12 +08:00
e585121011 Merge branch 'bugfix/backtrace_from_interrupts_backport_v3.2' into 'release/v3.2'
Make backtrace work across interrupts (backport v3.2)

See merge request idf/esp-idf!4183
2019-01-30 13:11:29 +08:00
671be20cc5 Merge branch 'bugfix/regenerate_sdkconfig_fails_v3.2' into 'release/v3.2'
Fix issues with regenerating sdkconfig on modification (backport v3.2)

See merge request idf/esp-idf!4169
2019-01-30 09:27:47 +08:00
022a9295b0 confgen: disable config override warnings 2019-01-29 20:50:51 +08:00
a34d788a5e kconfiglib: allow disabling of config override warnings
Patches ESP-IDF copy of kconfiglib.py with modifications in commit
b65baa47f69ae4c3993876a7edf0da0075aa70ff from kconfiglib repository.
2019-01-29 20:50:51 +08:00
2a47c5c7a4 esp32: fix WPS thread-safe
Fix WPS thread-safe bug
2019-01-29 19:44:24 +08:00
cfc4f74b52 Merge branch 'bugfix/coex_update_phy_to_fix_interrupt_wdt_v3.2' into 'release/v3.2'
esp32: update libphy.a to fix interrupt watchdog when WiFi and BT run at the same time and both enable modem sleep (backport v3.2)

See merge request idf/esp-idf!4192
2019-01-29 19:41:36 +08:00
43a722f0de mdns: fixed crash on free undefined ptr after skipped strdup
Shortcircuit evaluation may cause skip of _mdns_strdup_check of any further question field, which after clear_rx_packet freed undefined memory.
Fixes https://ezredmine.espressif.cn:8765/issues/28465
2019-01-29 10:34:04 +01:00
eff24857bc esp32: update libphy.a to fix interrupt watchdog when WiFi and BT run at
the same time and both enable modem sleep
2019-01-29 11:05:15 +08:00
18118a6d5c Merge branch 'bugfix/mdns_crash_free_strdup_3.2' into 'release/v3.2'
mdns: fixed crash on free undefined ptr if strdup is skipped (Backport 3.2)

See merge request idf/esp-idf!4190
2019-01-29 10:37:25 +08:00
64757c0228 mdns: fixed crash on free undefined ptr after skipped strdup
Shortcircuit evaluation may cause skip of _mdns_strdup_check of any further question field, which after clear_rx_packet freed undefined memory.
Fixes https://ezredmine.espressif.cn:8765/issues/28465
2019-01-28 20:17:37 +01:00
bab80ad202 freertos: Make backtrace work across interrupts (backport v3.2)
This commit adds the ability for backtracing to trace from the itnerrupt to the
task stack, and across nested interrupts. Test cases have also been added.

See MR !4084
2019-01-29 02:22:04 +08:00
76f0dda3a4 Merge branch 'mesh/bugfix_backport_v3.2' into 'release/v3.2'
Mesh/bugfix backport v3.2

See merge request idf/esp-idf!4117
2019-01-28 14:05:51 +08:00
ce9878ce71 modify test case to support ipv6 2019-01-26 13:03:35 +00:00
403a24ab64 confgen: disable redundant assignment warning 2019-01-25 18:49:55 +08:00
d2cf266762 kconfiglib: allow disabling of redundant definition warnings
Patches ESP-IDF copy of kconfiglib.py with modifications in commit
94c63de77c7a3422347e59e168b05174d0b9e84d from kconfiglib repository.
2019-01-25 18:49:55 +08:00
cec39b750a tool: Add unit test for Kconfig gen 2019-01-25 14:11:35 +08:00
0420f290a4 docs: remove invalid arg in confgen invocation on docs generation 2019-01-25 14:11:35 +08:00
eb6dbeb15a cmake: only generate sdkconfig on top level project 2019-01-25 14:11:35 +08:00
5c9ab21d81 confgen: base config creation on output type args 2019-01-25 14:11:35 +08:00
bab379faf8 Merge branch 'bugfix/i2c_master_clear_bus_v3.2' into 'release/v3.2'
i2c/fix i2c_master_clear_bus (backport v3.2)

See merge request idf/esp-idf!4127
2019-01-25 13:52:48 +08:00
fb7cd2a7a7 Merge branch 'bugfix/ble_active_scan_not_wait_scan_rsp_v3.2' into 'release/v3.2'
component/bt: add a option to make report adv data and scan response individually (backport v3.2)

See merge request idf/esp-idf!4157
2019-01-25 13:52:16 +08:00
c208a6b451 Merge branch 'bugfix/mqtt_tests_local_broker_v3.2' into 'release/v3.2'
MQTT tests: connect to local broker in CI (Backport 3.2)

See merge request idf/esp-idf!4119
2019-01-24 22:00:26 +08:00
78511c3cc3 component/bt: add a option to make report adv data and scan response individually
Originally, when doing BLE active scan, Bluedroid will not report adv to
application layer until receive scan response. This option is used to
disable the behavior. When enable this option, Bluedroid will report
adv data or scan response to application layer immediately.
2019-01-24 14:43:36 +08:00
cd6bbaa727 Merge branch 'bugfix/bootloader_map_size_v3.2' into 'release/v3.2'
bootloader: fix incorrect mapping size (backport v3.2)

See merge request idf/esp-idf!4138
2019-01-24 14:09:35 +08:00
55b8f2ea8c Merge branch 'bugfix/sha_ownership_v3.2' into 'release/v3.2'
hwcrypto sha: Allow SHA contexts to be shared between tasks (backport v3.2)

See merge request idf/esp-idf!4143
2019-01-24 14:08:35 +08:00
ec2f1a6b9a test: modify the reason code from 204 to 15 in WIFI_CONN_0904 2019-01-24 11:33:06 +08:00
26646b5b31 mesh: bugfix
1. fix network channel switch function.
2. support not configuring the network channel.
3. support not configuring the router BSSID even if the router is hidden.
4. add allow_channel_switch to mesh configuration.
5. add allow_router_switch to mesh router configuration.
6. support handling beacon without IE of DS Parameter Set.
7. fix Wi-Fi RX fails in a specific scenario (update libphy.a).
8. fix STAs can not detect disconnection from AP when encrypt transmission is used.
9. fix can not find hidden APs.
10. for root, modify the active scan time to 120ms.
11. remove all rc when clear parent Wi-Fi configuration.
12. fix memory leak caused by the remove announcement being sent is not released when esp_mesh_stop() is called.
13. fix modify IE encrypt after mesh is started.
14. ignore esp_mesh_connect() if mesh automatic reconnection is enabled.
15. fix reason is cleared before vote is done.
16. fix issues in the example of manual_networking when mesh network is encrypted.
17. detect and fix root conflicts when router BSSID is not set.
18. when root can not connect to the router due to NO_MORE_STAS(reason code:5), root will stop re-connection and perform MESH_NWK_LOOK_FOR_NETWORK.
19. wifi: fix the disconnection caused by receiving a deauth frame from non-parent node during scanning.
20. fix routing table redundant issue due to the remove announcement is not 100% reliable.
21. modify the max routes limitation from 300 to 1000.
22. wifi: fix ap does not deauth the sta which has not yet completed the 4-way handshake but the max replay count is reached.
2019-01-24 11:31:00 +08:00
1ae9a2ae0b Merge branch 'bugfix/wifi_fix_invalid_csi_data_index_v3.2' into 'release/v3.2'
esp32: fix invalid channel state information(CSI) data index (backort v3.2)

See merge request idf/esp-idf!4129
2019-01-23 22:14:04 +08:00
28eb488892 Merge branch 'bugfix/vfs_unregister_nested_v3.2' into 'release/v3.2'
vfs: fix unregister removing top level VFS instead of nested (backport v3.2)

See merge request idf/esp-idf!4137
2019-01-23 21:54:50 +08:00
fcf1dba9cd Merge branch 'bugfix/init_memctl_v3.2' into 'release/v3.2'
bootloader, esp32: add workaround for Tensilica erratum 572 (backport v3.2)

See merge request idf/esp-idf!4134
2019-01-23 21:43:58 +08:00
94ed7b8298 hwcrypto sha: Use spinlocks instead of semaphores for small state changes
Significant performance improvement and smaller RAM footprint.
2019-01-23 18:18:13 +08:00
24fab0b7a9 hwcrypto sha: Allow SHA contexts to be shared between tasks
Previously, hardware SHA engine "locks" were mutex semaphores. This meant that the task which
started a particular SHA session (in hardware) needed to finalise that session, or an invalid
FreeRTOS state was created.

Replace with binary semaphore which can be shared between tasks.

Includes a unit test, but unit test doesn't crash even without this fix
(some other unknown condition is required).
2019-01-23 18:18:13 +08:00
c4c1af114e Update esptool.py to v2.6 2019-01-23 17:02:02 +08:00
b1ee25afde bootloader: account for load address when mapping cache pages
Bootloader used to calculate the number of cache pages assuming that
load address was aligned, while in reality load address for DROM and
IROM was offset by 0x20 bytes from the start of 64kB page. This
caused the bootloader to map one less page if the size of the image
was 0x4..0x1c less than a multiple of 64kB.

Reported in https://esp32.com/viewtopic.php?f=13&t=6952.
2019-01-23 17:02:02 +08:00
cccaa68467 bootloader: fix IROM and DROM swapped in log messages 2019-01-23 17:02:02 +08:00
6080767379 vfs: fix unregister removing top level VFS instead of nested
Credits @neoniousTR.

Fixes https://github.com/espressif/esp-idf/pull/2770
2019-01-23 16:28:48 +08:00
42b6c4953d bootloader, esp32: add workaround for Tensilica erratum 572
If zero-overhead loop buffer is enabled, under certain rare conditions
when executing a zero-overhead loop, the CPU may attempt to execute an invalid instruction. Work around by disabling the buffer.
2019-01-23 16:23:56 +08:00
746e831c19 esp32: fix invalid channel state information(CSI) data index
Due to a hardware limitation in ESP32, the first four bytes of some
    CSI data is invalid, not the last four bytes.

    Correct a mistake of CSI sub-carrier index in documentation.
2019-01-22 20:30:05 +08:00
36f9091e03 ci, examples: use sdkconfig.ci as an extra defaults file, if present
- Allows placing CI-specific settings into sdkconfig.ci file
- Allows substituting environment variables in sdkconfig.ci
2019-01-22 10:15:10 +01:00
553ba51924 bugfix(i2c): reduce speed of I2C master bus reset routine and release SDA
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.
2019-01-22 11:43:55 +08:00
929d98538e 1. Slow down I2C to 100khz During Reset
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!
2019-01-22 11:43:40 +08:00
b810b32675 reduce speed of i2c master bus reset routine and release sda 2019-01-22 11:43:28 +08:00
00bf376bc3 mqtt tests: connect to local broker when running in CI to make the tests more reliable 2019-01-21 06:36:02 +01:00
fe19ea977b Merge branch 'bugfix/phy_rtc_cache_disabled_v3.2' into 'release/v3.2'
Fix PHY/RTC functions called in ISR, but stored in flash

See merge request idf/esp-idf!4114
2019-01-18 10:54:03 +08:00
a953f73c64 Fix some bugs in phy
1. fix bug PHY/RTC functions called in ISR (update phy to v4007)
2. add UnitTest to test it
3. fix task watchdog bug when wifi change channel
4. disable/enable agc to mac deinit/init
2019-01-16 22:04:49 +08:00
bed50a93f0 Merge branch 'bugfix/wifi_fix_incorrect_tx_complete_state_v3.2' into 'release/v3.2'
esp32: fix the incorrect tx complete state issue (backport v3.2)

See merge request idf/esp-idf!4105
2019-01-13 00:10:50 +08:00
a80bfc1dcf esp32: fix the incorrect tx complete state issue 2019-01-12 19:40:52 +08:00
51d846417e Merge branch 'bugfix/fix_ba_hardware_index_deleting_issue_v3.2' into 'release/v3.2'
esp32: fix wrongly deleting hardware BA index bug (backport v3.2)

See merge request idf/esp-idf!4102
2019-01-12 14:23:33 +08:00
ca54a5ce2a esp32: fix wrongly deleting hardware BA index bug
Fix the bug that hardware BA index will be wrongly removed in
WiFi mode WIFI_MODE_APSTA.
2019-01-11 21:46:28 +08:00
7b1777dd30 Merge branch 'bugfix/wifi_defragmentation_only_for_data_frame_v3.2' into 'release/v3.2'
esp32: do defragmentation only for data and management frame (backport v3.2)

See merge request idf/esp-idf!4090
2019-01-11 21:25:19 +08:00
64b46ff1d9 Merge branch 'bugfix/check_dependencies_msys_v3.2' into 'release/v3.2'
tools: Be more helpful to MSYS32 users with package installation & check if current python is inside virtual environment (backport v3.2)

See merge request idf/esp-idf!4063
2019-01-11 15:42:20 +08:00
c355d8a88e python: Add check if current python is inside virtual environment 2019-01-10 09:37:21 +01:00
977af32d0f tools: Be more helpful to MSYS32 users with package installation 2019-01-10 09:37:02 +01:00
f0a6432717 esp32: do defragmentation only for data and management frame
Check frame type before defragmentation. Only data and management frame
    can do defragmentation.
2019-01-10 14:17:21 +08:00
c18e86a826 Merge branch 'bugfix/coex_unforce_wifi_if_no_data_buffered_in_beacon_v3.2' into 'release/v3.2'
esp32: unforce wifi if receiving beacon with no data buffered in dream (backport v3.2)

See merge request idf/esp-idf!4036
2019-01-10 14:11:02 +08:00
b5d53a0eff Merge branch 'bugfix/timer_delete_dispatch_race_v3.2' into 'release/v3.2'
esp_timer: do not allow deleting timers while callbacks are dispatched (backport v3.2)

See merge request idf/esp-idf!4062
2019-01-10 13:44:15 +08:00
10afc3de77 esp32: unforce wifi if receiving beacon with no data buffered in dream
state and reduce force receiving broadcast data time

    1. If receiving beacon which indicates that there is no data buffered,
    do not force to receive WiFi data.
    2. If receiving beacon which indicates that there is broadcast data
    buffered, reduce the time to force receiving broadcast data.
2019-01-09 14:13:08 +08:00
545878d4e9 Merge branch 'bugfix/ignore_windows_conf_tools_v32' into 'release/v3.2'
gitignore: Add mconf-idf.exe and conf-idf.exe (v3.2)

See merge request idf/esp-idf!4071
2019-01-09 13:57:54 +08:00
ec7909956d Merge branch 'bugfix/fix_mbox_thread_safe_issue_v3.2' into 'release/v3.2'
tcpip: fix mbox thread-safe issue  (backport v3.2)

See merge request idf/esp-idf!4005
2019-01-09 10:21:22 +08:00
d9c3a08813 Merge branch 'bugfix/mdns_udp_send_protected_backport3.2' into 'release/v3.2'
mdns networking udp send protected (Backport 3.2)

See merge request idf/esp-idf!4020
2019-01-08 12:04:23 +08:00
eb9a93f9b7 Merge branch 'bugfix/mdns_crash_when_query_backport3.2' into 'release/v3.2'
mdns crash when query (backport 3.2)

See merge request idf/esp-idf!3950
2019-01-08 12:03:52 +08:00
710019a47f Merge branch 'bugfix/fix_the_country_code_bug_v3.2' into 'release/v3.2'
wifi: fix the bug that STA can scan the channel out of the country regdomain range (backport v3.2)

See merge request idf/esp-idf!4068
2019-01-07 20:33:02 +08:00
2d27358f61 Merge branch 'feature/i2s_tx_descriptor_auto_clear_backport_v3.2' into 'release/v3.2'
i2s: add (optional) support to clear tx descriptor in underflow case (backport v3.2)

See merge request idf/esp-idf!4056
2019-01-07 16:34:01 +08:00
b80eba8d5a wifi: fix the bug that STA can scan the channel out of the country regdomain range 2019-01-04 14:34:36 +08:00
7832db7bb3 gitignore: Add mconf-idf.exe and conf-idf.exe
Problem since f6cd55d2ac

Closes https://github.com/espressif/esp-idf/issues/2751
2019-01-04 10:09:35 +11:00
efa70bc8e3 lwip: fix mbox thread-safe issue
Fix a mbox free thread-safe issue that can lead to crash in sys_arch_mbox_fetch.
2019-01-02 22:48:19 +08:00
31b7db5c38 esp_timer: do not allow deleting timers while callbacks are dispatched
timer_process_alarm function of esp_timer holds a spinlock for the
entire duration of its operation, except for the time when timer
callback function is called. It is possible that when
timer_process_alarm releases the spinlock, a higher priority task may
run and delete the timer. Then the execution will return to
timer_process_alarm, and this will either cause a crash, or undesired
execution of callback after the timer has been stopped or deleted.

To solve this problem, add a mutex which will prevent deletion of timers
while callbacks are being dispatched.
2019-01-02 20:06:06 +11:00
8d02ccd2f7 examples: enable option to auto clear I2S tx descriptor on underflow
Closes: https://github.com/espressif/esp-idf/issues/1945
(cherry picked from commit 1751607adf)
2018-12-31 13:43:34 +05:30
62eb0f4c12 i2s: add (optional) support to clear tx descriptor in underflow case
It has been observed that, in case of underflow (data unavailability) in
I2S transmission, previously filled up tx descriptors continue to get
transmitted on line, causing noise in case of audio use case.

This change adds optional `tx_desc_auto_clear` field during I2S driver intialization
than can zero initialize tx descriptor in case of underflow situation in
interrupt handler itself.

Closes: https://github.com/espressif/esp-idf/issues/1789
(cherry picked from commit 765bf674d0)
2018-12-31 13:42:26 +05:30
155f034b1e Merge branch 'feature/freemodbus_move_rs485_mode_control_v3.2' into 'release/v3.2'
examples: freemodbus port serial slave move uart mode settings into example (backport v3.2)

See merge request idf/esp-idf!4015
2018-12-29 10:28:27 +08:00
47dea73b03 Merge branch 'doc/btdm_modem_sleep_EVED_mode_for_v3.2' into 'release/v3.2'
doc/btdm_modem_sleep_EVED_mode_for_v3.2(backport v3.2)

See merge request idf/esp-idf!4016
2018-12-29 10:27:52 +08:00
28fdf96828 Merge branch 'bugfix/ota_magic_byte_issue_v3.2' into 'release/v3.2'
Bugfix/ota magic byte issue v3.2(backport v3.2)

See merge request idf/esp-idf!4004
2018-12-29 10:24:24 +08:00
3969fe0dad Merge branch 'bugfix/lwip_add_hostname_option_in_dhcp_discover_v3.2' into 'release/v3.2'
add hostname option in dhcp discover (backport v3.2)

See merge request idf/esp-idf!3938
2018-12-29 10:07:50 +08:00
c70c25afd0 Merge branch 'mesh/bugfix_v3.2' into 'release/v3.2'
mesh: when no parent is found, send probe request

See merge request idf/esp-idf!3940
2018-12-28 14:02:23 +08:00
d59d9eef4f Merge branch 'bugfix/bbpll_wakeup_reset_v3.2' into 'release/v3.2'
BBPLL reset fixes (backport v3.2)

See merge request idf/esp-idf!4011
2018-12-24 18:16:47 +08:00
22514e12d8 mdns: fix networking running udp_sendif from lwip thread 2018-12-21 16:44:15 +01:00
f48ffb37f2 mdns: check all mallocs for failure and add default hook to log error with free heap
solves crash about _mdns_result_txt_create when stress test
2018-12-21 16:27:58 +01:00
0f041ee7bb mdns: fixed static memory leak 2018-12-21 16:26:39 +01:00
c320a3ee4c mdns: resolve memory leak when txt record received multiple times 2018-12-21 16:26:39 +01:00
1f35716ef4 mdns: skip sending search when finished, not properly locked timer task 2018-12-21 16:26:39 +01:00
358de85eb3 component/bt: add more information and description for bluetooth modem sleep
Add remark that "EVED" mode for bluetooth modem sleep is only used for internal test
2018-12-21 19:29:47 +08:00
84277e5887 mesh: when no parent is found, send probe request via broadcast
1. fix error in checking Wi-Fi commit ID.
2018-12-21 17:49:58 +08:00
52a70e0489 Merge branch 'bugfix/ext_ram_bss_align_v3.2' into 'release/v3.2'
Fix ext_ram_bss alignment crash (backport v3.2)

See merge request idf/esp-idf!4014
2018-12-21 17:31:33 +08:00
6523d912f2 examples: freemodbus port serial slave move uart mode settings into example
Update freemodbus component file esp-idf/components/freemodbus/port/portserial.c to remove UART mode settings;
Move UART mode settings into esp-idf/examples/protocols/modbus_slave/main/freemodbus.c
Move UART pin settings from Component config into example Kconfig.projbuild file
Move setup of UART port pins from freemodbus component into example file

TW#27721
Closes https://github.com/espressif/esp-idf/issues/2784#issuecomment-443600157
2018-12-21 09:54:26 +01:00
aa0d2078b7 psram: Use 8-bit type for _ext_ram_bss_start/_ext_ram_bss_end
Fixes pointer arithmetic when printing size of remaining heap
2018-12-21 19:03:12 +11:00
348d6d5d3f multi_heap: Fix bug when start of heap is unaligned
Alignment was accounted for in one place only.

TW27954
2018-12-21 19:03:12 +11:00
46228db9a8 linker external bss: Align end of ext bss to word boundary
TW27954
2018-12-21 19:03:12 +11:00
2cac11f162 Merge branch 'bugfix/btdm_fix_crash_adv_scan_coex_v3.2' into 'release/v3.2'
component/bt: fix crash when adv and scan coex and optimize duplicate scan (backport v3.2)

See merge request idf/esp-idf!3994
2018-12-21 15:59:53 +08:00
64eeee4532 Merge branch 'bugfix/btdm_fix_two_bugs_about_pairing_v3.2' into 'release/v3.2'
components/bt: Fix two bugs about pairing(backport 3.2)

See merge request idf/esp-idf!3995
2018-12-21 14:26:19 +08:00
a9eb37e2c8 Merge branch 'bugfix/btdm_prevent_light_sleep_for_v3.2' into 'release/v3.2'
bugfix/btdm_prevent_light_sleep_for_v3.2(backport v3.2)

See merge request idf/esp-idf!3986
2018-12-21 14:25:49 +08:00
c7a297195f soc/rtc: reset another BBPLL related register
Follow-up to b21ffc8a: an additional register needs to be reset.

Ref. https://github.com/espressif/esp-idf/issues/2711
2018-12-21 12:40:08 +08:00
19e96add8a soc/rtc: reset BBPLL configuration after enabling it
A workaround to reset BBPLL configuration after light sleep. Fixes the
issue that Wi-Fi can not receive packets after waking up from light
sleep.

Ref. https://github.com/espressif/esp-idf/issues/2711
2018-12-21 12:39:49 +08:00
a0a0328e4f Merge branch 'bugfix/idf_monitor_without_toolchain_v3.2' into 'release/v3.2'
tools: Print useful error message from idf_monitor when toolchain isn't available (backport v3.2)

See merge request idf/esp-idf!3949
2018-12-21 12:01:54 +08:00
04aebc464c bugfix/ota_magic_byte_issue: Fix indent and replace constant by macro
Replace 0xE9 by ESP_IMAGE_HEADER_MAGIC.
2018-12-20 12:29:25 +05:30
30e01847ad bugfix/ota_magic_byte_issue: Fixes OTA magic byte error
On enabling flash encryption, OTA fails with magic byte error in the second chunk
if the http data is split into two or more chunks and first chunk is less than 16.
2018-12-20 12:29:00 +05:30
zwj
3f6033d8bd fix crash when adv and scan coex and optimize duplicate scan 2018-12-19 19:53:01 +08:00
45e59a9f56 components/bt: Fix two bugs about pairing
1. Fix Legacy Pairing failed without remote device name
2. Fix discovery no device after disabling SSP
2018-12-19 19:42:47 +08:00
587e6ec93f component/bt: use a pm_lock to prevent light sleep when bluetooth is enabled due to current imcompatibility 2018-12-18 14:51:19 +08:00
6d00c7fc49 Merge branch 'bugfix/btdm_assert_ble_65536_v3.2' into 'release/v3.2'
fix bug that there's very low ratio to cause BLE assert(65536, 0) in rwble.c at line 222

See merge request idf/esp-idf!3968
2018-12-18 12:03:21 +08:00
c418714ec6 Merge branch 'bugfix/btdm_fix_receive_adv_pkt_when_duplicate_scan_enabled_v3.2' into 'release/v3.2'
Component/bt: fix receive adv pkt when enable duplicate scan (backport v3.2)

See merge request idf/esp-idf!3942
2018-12-18 11:45:28 +08:00
19d8c050cd Merge branch 'bugfix/tw27963_fix_wifi_stop_bug_v3.2' into 'release/v3.2'
esp32: fix WiFi stop bug in WiFi/BT coexist mode (backport v3.2)

See merge request idf/esp-idf!3982
2018-12-18 11:41:03 +08:00
cb650382ca esp32: fix WiFi stop bug in WiFi/BT coexist mode
This fix includes following changes:
1. Fix the bug that esp_restart()/esp_wifi_stop() sometimes fails in WiFi/BT coexist mode.
2. Add a timer for WiFi stop and stop WiFi forcibly once the timer expires.
2018-12-17 20:52:40 +08:00
e5e592e5b6 fix bug that there's very low ratio to cause BLE assert(65536, 0) in rwble.c at line 222 2018-12-17 20:50:42 +08:00
28e20e90e3 Component/bt: fix receive adv pkt when enable duplicate scan 2018-12-17 15:51:28 +08:00
1c4d9f2aca Merge branch 'bugfix/btdm_modem_sleep_cowork_with_DFS_for_v3.2' into 'release/v3.2'
Bugfix/btdm modem sleep cowork with dfs for v3.2(backport v3.2)

See merge request idf/esp-idf!3962
2018-12-14 20:28:31 +08:00
ded8b0102a Merge branch 'bugfix/btdm_fix_auth_mode_error_when_reconnection_in_smp_v3.2' into 'release/v3.2'
Component/bt: fix auth_mode error when reconnection in SMP (backport v3.2)

See merge request idf/esp-idf!3955
2018-12-14 18:24:01 +08:00
401970495d component/bt: add DRAM_ATTR attribute to global variables(mostly in bss segment) in bt.c which can be accessed in ISR 2018-12-14 14:59:41 +08:00
5d46bb596d Merge branch 'bufix/btdm_fix_save_key_when_auth_mode_without_bond_v3.2' into 'release/v3.2'
Component/bt: fix save keys when auth mode without bond (backport V3.2)

See merge request idf/esp-idf!3957
2018-12-14 14:59:24 +08:00
8de9149b11 component/bt: bugfix of bluetooth modem sleep not being able to work with Dynamic Frequency Scaling
1. start an esp_timer on entering sleep to acquire pm_lock before wake up from modem sleep
2. decrease the clock division of XTAL fed to bluetooth low power clock from 32us to 2us period to allow to work under 240MHz Max CPU frequency
3. decrease the minimum sleep duration threshold to allow shorter bluetooth modem sleep period, especially for BLE with short connection interval
4. reconfigure bluetooth baseband(BT-BB) settings after PHY/RF init upon waking up from modem sleep to avoid packet RX/TX performance degradation
2018-12-14 14:56:29 +08:00
e8b8946e6e tools: Print useful error message from idf_monitor when toolchain isn't available 2018-12-13 22:03:25 +01:00
2c1e3d1ef2 Component/bt: fix save keys when auth mode without bond 2018-12-13 15:45:53 +08:00
bf608b6709 Component/bt: fix auth_mode error when reconnection in SMP 2018-12-13 15:33:37 +08:00
24ebdbd3f4 Merge branch 'test/add_case_to_detect_ds2ds_issue_v3.2' into 'release/v3.2'
test: add case to detect ds2ds issue (backport v3.2)

See merge request idf/esp-idf!3851
2018-12-13 14:52:58 +08:00
fd00d3213b Merge branch 'bugfix/btdm_fix_accept_specified_sec_auth_v3.2' into 'release/v3.2'
Component/bt: fix accept specified sec auth error(backport v3.2)

See merge request idf/esp-idf!3836
2018-12-13 11:20:02 +08:00
c921a5bc4b Merge branch 'feature/illegal_instruction_panic_info_v3.2' into 'release/v3.2'
panic: dump some instruction memory on IllegalInstruction exception (backport v3.2)

See merge request idf/esp-idf!3946
2018-12-12 15:58:22 +08:00
ade85cc850 panic: dump some instruction memory on IllegalInstruction exception 2018-12-12 11:58:55 +08:00
5c8d25b795 add hostname option in dhcp discover
Hostname option has been removed from dhcp discover since IDFv3.2.
But it remains in dhcp request due to which ESP32 can not get IPv4 address
from some APs. Re-add hostname option to dhcp discover to solve this issue.
2018-12-10 21:26:24 +08:00
ac051f0afc Merge branch 'bugfix/btdm_assert_ble_32768_v3.2' into 'release/v3.2'
fix bug that there's very low ratio to cause BLE assert(32768, 0) in rwble.c at line 222

See merge request idf/esp-idf!3919
2018-12-10 15:04:44 +08:00
bb47146710 Merge branch 'fix/spi_callback_in_iram_v3.2' into 'release/v3.2'
spi: fix the crash when callbacks are not in the IRAM (Backports v3.2)

See merge request idf/esp-idf!3884
2018-12-07 10:37:07 +08:00
07cb228f64 Merge branch 'bugfix/win_path_print_v3.2' into 'release/v3.2'
tools: correct printed path on MS Win (backport v3.2)

See merge request idf/esp-idf!3913
2018-12-07 10:36:31 +08:00
3cfe1c89b5 Merge branch 'ci/combine_unit_test_and_integration_test_v3.2' into 'release/v3.2'
ci: combine unit_test and integration_test stage (backport v3.2)

See merge request idf/esp-idf!3845
2018-12-07 10:36:00 +08:00
4f805d558c Merge branch 'bugfix/fix_uart_read_bug_when_using_dual_core_v3.2' into 'release/v3.2'
driver(uart): fixed uart read error bug when using dual core (backport v3.2)

See merge request idf/esp-idf!3813
2018-12-07 10:35:17 +08:00
f53716d851 Merge branch 'bugfix/idfpy_monitor_msys_v3.2' into 'release/v3.2'
tools: fix idf.py monitor for MSYS (backport v3.2)

See merge request idf/esp-idf!3898
2018-12-07 10:34:44 +08:00
f8fd922ca5 unit-test-app: fix the RegEx to detect test case:
tags are not correctly parsed if eol do not contain `\r`
2018-12-07 02:04:55 +00:00
61d07ffbfc tiny-test-fw: fix exception when expect RegEx:
match.groups() could return None. We can't do decode on None object.
2018-12-07 02:04:55 +00:00
6b5649190f test: add test case to receive ds2ds packet 2018-12-07 02:04:55 +00:00
f44507de53 fix bug that there's very low ratio to cause BLE assert(32768, 0) in rwble.c at line 222 2018-12-06 21:35:19 +08:00
88c7a61a63 tools: correct the coding style of check_python_dependencies.py 2018-12-06 08:33:17 +01:00
6af90457f7 tools: correct printed path on MS Win 2018-12-06 08:32:45 +01:00
3aafb2cfcf Merge branch 'bugfix/ethernet_enable_second_failure_v3.2' into 'release/v3.2'
fix phy init timeout(backport v3.2)

See merge request idf/esp-idf!3896
2018-12-06 15:22:32 +08:00
8ec0c82c3f tools: fix idf.py monitor for MSYS 2018-12-05 10:48:30 +01:00
a338c1b712 ethernet: phy init timeout
When ethernet enable again after disable it before, phy init will report timeout.
The cause of this problem is that the enabling of emac clock is too late, and should be placed before phy init.
2018-12-05 16:32:24 +08:00
0b21be508e Merge branch 'bugfix/btdm_bugs_caused_by_coex_v3.2' into 'release/v3.2'
component/bt and esp32:  fix two bluetooth bugs that caused by coexist module

See merge request idf/esp-idf!3861
2018-12-05 14:17:25 +08:00
3b4d51bbfa Merge branch 'doc/security_features_small_fixes_v3.2' into 'release/v3.2'
doc: Small secure boot & flash encryption corrections (v3.2)

See merge request idf/esp-idf!3888
2018-12-05 11:07:41 +08:00
60c556eb55 docs: flash encryption: Fix description of behaviour when all bits of FLASH_CRYPT_CNT are set
Correct behaviour is described in section 25.3.3 Flash Decryption Block of the ESP32 TRM
2018-12-05 11:20:05 +11:00
9933e37c8b doc: secure boot: Explain output of digest_secure_bootloader command
Mentioned on forum https://esp32.com/viewtopic.php?f=13&t=8162&start=10#p34714
2018-12-05 11:20:05 +11:00
67bdc8aaf4 doc: security: Use less ambiguous language about using bot flash encryption & secure boot together 2018-12-05 11:20:05 +11:00
44bd6f72bc spi: fix the crash when callbacks are not in the IRAM
Introduced in 9c23b8e5 and 4f87a62f. To get higher speed, menuconfig
options are added to put ISR and other functions into the IRAM.  The
interrupt flag ESP_INTR_FLAG_IRAM is also mistakenly set when the ISR is
put into the IRAM. However callbacks, which are wrote by the user, are
called in the master and slave ISR. The user may not be aware of that
these callbacks are not disabled during flash operations. Any cache miss
during flash operation will cause panic.

Essentially IRAM functions and intrrupt flag ESP_INTR_FLAG_IRAM are
different, the latter means not disabling the ISR during flash
operations.  New bus_config flag intr_flags is offered to help set the
interrupt attribute, including priority level, SHARED, IRAM (not
disabled during flash operations).  It introduced a small BREAK to
IDFv3.1 (but the same as IDFv3.0) that the user has to manually set IRAM
flag now (therefore he's aware of the IRAM thing) to void the ISR being
disabled during flash operations.
2018-12-04 21:35:20 +08:00
2d67ce3109 component/bt and esp32: fix two bluetooth bugs that caused by coexist module
1. Fix interrupt watchdog timeout in bluetooth "btdm_bb_isr"
    2. Fix BLE assert(512) or assert(1536)  in rwble.c at line 222
    3. Update librtc.a to fix BLE assert(512) in rwble.c at line 222

    The #1 and #2 occurs random.
    The #3 bug occurs in certain scenario:
    	1. If Wifi start softap and BLE is working
    	2. If wifi start station, but do not use normal station operation, such
    		as just use espnow, while BLE is working
    	3. Any other scenario, that wifi works without use software coexist
    		operation, while BLE is working(such as do advertising and ...)

    4. update libcoexist.a version to v1.1.2
2018-12-03 19:30:28 +08:00
e85cb6d148 ci: combine unit_test and integration_test stage:
The number of runners of integration test is not bottleneck to CI
pipeline performance now. Combine these 2 stages will make integration
test executed even unit test fails. This could help us to collect more
info about test history.
2018-11-30 13:44:11 +08:00
7658b8ab62 Merge branch 'test/enhanced_junit_test_result_v3.2' into 'release/v3.2'
test: enhanced junit test result (backport v3.2)

See merge request idf/esp-idf!3794
2018-11-30 11:39:31 +08:00
7969a566e3 Merge branch 'bugfix/fat_lock_log_v3.2' into 'release/v3.2'
fatfs: Do not log from critical sections (backport v3.2)

See merge request idf/esp-idf!3721
2018-11-29 23:00:55 +08:00
be05b1e654 Merge branch 'bugfix/uart_select_buffer_v3.2' into 'release/v3.2'
VFS: select() on UART should return immediately when data is buffered (backport v3.2)

See merge request idf/esp-idf!3829
2018-11-29 23:00:17 +08:00
ca51b60033 Component/bt: fix accept specified sec auth error 2018-11-29 20:46:08 +08:00
9b3ff1bed0 Merge branch 'bugfix/i2c_hardware_filter_default_enable_v3.2' into 'release/v3.2'
driver(i2c): enable I2C master hardware filter by default for release/v3.2

See merge request idf/esp-idf!3815
2018-11-29 19:28:32 +08:00
f859f9e25b VFS: select() on UART should return immediately when data is buffered 2018-11-29 10:08:26 +01:00
f2ae151dab Merge branch 'bugfix/btdm_rf_reg_v3.2' into 'release/v3.2'
fix bug to unsupport rf reg access from hci cmd

See merge request idf/esp-idf!3786
2018-11-28 21:20:05 +08:00
bae0d8a313 driver(i2c): enable I2C master hardware filter by default for release/v3.2 2018-11-28 17:02:04 +08:00
cfcc0edc33 driver(uart): fixed uart read error bug when using dual core for release/v3.2. 2018-11-28 16:37:59 +08:00
54e6f0793a ci: split build unit test job:
it takes long time to build with both make and cmake
2018-11-26 21:59:42 +08:00
e98f4d2751 ci: use artifacts:reports feature of Gitlab CI 2018-11-26 17:06:41 +08:00
33cf0faac8 ci: assign unit test cases in sequence of config and name 2018-11-26 17:06:40 +08:00
7385e71c84 test: fix unit test script code style warnings 2018-11-26 17:05:04 +08:00
7778ce83bd test: generate junit test report according to executed cases 2018-11-26 17:05:04 +08:00
0f8070a6fd tiny-test-fw: support capture raw data in DUT:
test cases might want to use `expect` and get raw data from DUT at the same time. New added capture method provides a way to do that.
2018-11-26 17:05:04 +08:00
0fcb9056f8 tiny-test-fw: enhanced junit test report support:
1. replace xunitgen with junit_xml, which can log more info
2. allow test cases to handle junit test report by them own
3. allow test cases to log some info into report via `sysout` tag
2018-11-26 17:05:04 +08:00
5110d4b303 fatfs: Do not log from critical sections
Logging in the critical section can result in a deadlock when the logger
is redirected to FATFS.

Closes https://github.com/espressif/esp-idf/issues/1693
2018-11-26 09:21:44 +01:00
fc19954376 Merge branch 'bugfix/adjtime_test2_v3.2' into 'release/v3.2'
Resolve ""test for thread safety adjtime and gettimeofday functions" fails randomly"  (backport v3.2)

See merge request idf/esp-idf!3791
2018-11-26 16:17:05 +08:00
16d32c58e7 newlib: Fix UT adjtime 2018-11-26 15:55:17 +11:00
3d926da642 Merge branch 'bugfix/fix_cmake_args_issue_backport_3.2' into 'release/v3.2'
Fix cmake args issue (backport 3.2)

See merge request idf/esp-idf!3789
2018-11-26 09:53:38 +08:00
9bb719dd68 fix bug to unsupport rf reg access from hci cmd
Always return 0 when read rf register and do nothing when write rf register
2018-11-24 14:21:25 +08:00
536cb0489e Merge branch 'bugfix/fix_some_wifi_bugs_1121_v3.2' into 'release/v3.2'
esp32: fix some wifi bugs (backport v3.2)

See merge request idf/esp-idf!3762
2018-11-23 17:08:31 +08:00
98c7cb5560 cmake: remove unecessary info passed to bootloader build 2018-11-23 16:12:14 +08:00
4baf333c79 ulp: fix passing ulp srcs due to cmake_args bug 2018-11-23 16:10:54 +08:00
79401934a1 Merge branch 'bugfix/backports_v3.2' into 'release/v3.2'
Multiple v3.2 backports

See merge request idf/esp-idf!3727
2018-11-23 13:43:24 +08:00
ec1daf32e1 Merge branch 'bugfix/btdm_move_func_into_iram_v3.2' into 'release/v3.2'
components/bt: Move function in interrupt into IRAM(backport 3.2)

See merge request idf/esp-idf!3758
2018-11-23 13:39:27 +08:00
1cac0d2cf2 esp32: fix some wifi bugs
Fix some Wifi bugs:
1. Enable RX BAR
2. Fix the bug that ESP32 AP negotiates with iphone to 11g
3. Fix the bug that ESP32 STA has ap_loss because CMCC AP contains two SSID
2018-11-22 20:27:52 +08:00
8d1594c339 components/bt: Move function in interrupt into IRAM
1. Move function in interrupt into IRAM
2. Delete unused code, saving 240B DRAM and some code size
2018-11-22 16:19:21 +08:00
a0f516de0b Merge branch 'mesh/bugfix_v3.2_backport' into 'release/v3.2'
mesh: bugfix (backport3.2)

See merge request idf/esp-idf!3771
2018-11-22 10:22:12 +08:00
802d94aa35 utest: increase IDF_PERFORMANCE_MAX_VFS_OPEN_WRITE_CLOSE_TIME to 50000 2018-11-22 00:39:38 +08:00
3c3e375d8d mesh: bugfix
1. fix failture of mesh stop caused by block-sending.
2. fix when FIXED_ROOT is set, 2nd layer devices can not receive mesh event ESP_ERR_MESH_NO_PARENT_FOUND.
3. fix when FIXED_ROOT is set and the root turns off mesh function, 2nd layer devices do not look for new parents.
4. add APIs esp_mesh_disconnect() and esp_mesh_connect().
5. disconnect from parent/router when the DSSS channel in received beacon is different from the home channel.
6. remove nvs task to release 3k bytes memory.
2018-11-22 00:39:02 +08:00
d57ea422be Merge branch 'bugfix/cmake_utf_decode_v3.2' into 'release/v3.2'
tools: Fix Unicode decode error & indentation error (backport v3.2)

See merge request idf/esp-idf!3733
2018-11-21 11:44:54 +08:00
3b3242cbae freertos: use xTaskQueueMutex to protect tick count
Having two different spinlocks is problematic due to possibly
different order in which the locks will be taken. Changing the order
would require significant restructuring of kernel code which is
undesirable.

An additional place where taking xTickCountMutex was needed was in
vApplicationSleep function. Not taking xTickCountMutex resulted in
other CPU sometimes possibly advancing tick count while light sleep
entry/exit was happening. Taking xTickCountMutex in addition to
xTaskQueueMutex has shown a problem that in different code paths,
these two spinlocks could be taken in different order, leading to
(unlikely, but possible) deadlocks.
2018-11-21 03:42:15 +00:00
96c2b34eb9 pm: prevent entering light sleep again immediately after wakeup
When light sleep is finished on one CPU, it is possible that the other
CPU will enter light sleep again very soon, before interrupts on the
first CPU get a chance to run. To avoid such situation, set a flag
for the other CPU to skip light sleep attempt.
2018-11-21 03:42:15 +00:00
6b3a8acdc3 pm: fix entering light sleep in single core mode
Tickless idle/light sleep procedure had a bug in single core mode.
Consider the flow of events:
1. Idle task runs and calls vApplicationIdleHook
2. This calls esp_vApplicationIdleHook, which calls esp_pm_impl_idle_hook, and pm lock for RTOS on the current core is released.
3. Then esp_vApplicationIdleHook calls esp_pm_impl_waiti, which checks that s_entered_light_sleep[core_id]==false and goes into waiti state.
4. Some interrupt happens, calls esp_pm_impl_isr_hook, which takes pm lock for RTOS. PM state goes back to CPU_FREQ_MAX.
5. Once the interrupt is over, vApplicationIdleHook returns, and Idle task continues to run, finally reaching the call to vApplicationSleep.
6. vApplicationSleep does not enter light sleep, because esp_pm_impl_isr_hook has already changed PM state from IDLE to CPU_FREQ_MAX.

This didn’t happen in dual core mode, because waiti state of one CPU was interrupted by CCOMPARE update interrupt from the other CPU, in which case PM lock for FreeRTOS was not taken.

Fix by inverting the meaning of the flag (for convenience) and only setting it to true when vApplicationSleep actually fails to enter light sleep.
2018-11-21 03:42:15 +00:00
a10abd695b freertos: fix compilation warning in single core mode
When tickless idle is enabled
2018-11-21 03:42:15 +00:00
0f28a51996 spiffs: increase timeout in readdir test
Timeout of 15 seconds is not sufficient if SPIFFS partition needs to
be formatted, on some of the boards.
2018-11-21 03:42:15 +00:00
6681096e55 Merge branch 'bugfix/mdns_query_failed_after_init_v3.2' into 'release/v3.2'
Fixed: mdns query failed after init (Backport v3.2)

See merge request idf/esp-idf!3729
2018-11-21 11:41:34 +08:00
18b65dca26 Merge branch 'bugfix/btdm_controller_disable_v3.2' into 'release/v3.2'
Fix two bugs when disable bluetooth controller(backport v3.2)

See merge request idf/esp-idf!3716
2018-11-21 11:26:14 +08:00
a398116b1c Merge branch 'bugfix/btdm_add_check_peer_addr_type_in_set_adv_params_v3.2' into 'release/v3.2'
Component/bt: add check peer addr type in set adv params (backport v3.2)

See merge request idf/esp-idf!3734
2018-11-20 20:02:37 +08:00
331c7c7dc3 Fix two bugs when disable bluetooth controller
1. Fix the bug that disable controller suddenly cause crash when ble is working.
2. Fix the bug that when disable controller, it will cause wifi cannot RX, TX timeout, buffer lack and etc.
2018-11-20 09:01:57 +00:00
7bd9559e7e Merge branch 'bugfix/wifi_sta_sniffer_phy_config_bug_v3.2' into 'release/v3.2'
wifi: fix wifi sta and sniffer phy config bug (backport v3.2)

See merge request idf/esp-idf!3718
2018-11-20 14:20:29 +08:00
e84289077c Merge branch 'bugfix/fix_bug_ethernet_v3.2' into 'release/v3.2'
ethernet: fix some bugs in phy&mac driver(backport v3.2)

See merge request idf/esp-idf!3640
2018-11-19 17:54:27 +08:00
c59c40741b Component/bt: add check peer addr type in set adv params 2018-11-19 17:15:41 +08:00
f3c1903791 tools: Fix UTF decode error 2018-11-19 10:11:34 +01:00
2885ec3831 ethernet: multi-call failure in esp_eth_init
Because of incomplete state machine, ethernet driver will broken if esp_eth_init is called twice.
Detailed information here: https://ezredmine.espressif.cn:8765/issues/27332
2018-11-19 14:55:43 +08:00
a7db0e2291 ethernetif: fix potential memory leak
1. If L2_TO_L3_RX_BUF_MODE is not selected, we must assign l2_owner explictly before we call pbuf_free.
2. free intr resource in esp_eth_deinit

Closes https://github.com/espressif/esp-idf/issues/2670
2018-11-19 14:55:43 +08:00
cb98f5a814 ethernet: fix some bugs in phy&mac driver
1. Original register mapping for LAN8720 has some registers that doesn't exist/support.
So just remove them, and fix the power and init function for LAN8720.
2. GPIO16 and GPIO17 is occupied by PSRAM, so only ETH_CLOCK_GPIO_IN mode is supported in that case if using PSRAM.
3. Fix bug of OTA failing with Ethernet
4. Fix bug of multicast with Ethernet
5. Fix potential memory leak
2018-11-19 14:55:43 +08:00
8725bce5bc Merge branch 'bugfix/btdm_errors_in_comment_v3.2' into 'release/v3.2'
components/bt: Some errors in comment(backport 3.2)

See merge request idf/esp-idf!3713
2018-11-19 14:36:45 +08:00
174b3b89e4 mdns: sending search packets also in probing and announcing state
mdns queries did not work properly when send imeadiately after set_hostname, which cuased reinit of pcb and therefore restarted probing, so search packets were blocked until probing finished
closes #2507, closes #2593
2018-11-19 04:38:04 +01:00
8d9d8e27ca wifi: fix the bug that if station (sleep is enabled) and sniffer are enabled at the same time,
when disable sniffer, station will never enable phy and rf again.
2018-11-16 19:09:31 +08:00
93f4dc6b32 Merge branch 'bugfix/btdm_fuction_in_isr_is_not_in_iram_v3.2' into 'release/v3.2'
components/bt: Put function in isr into iram(backport 3.2)

See merge request idf/esp-idf!3689
2018-11-16 18:15:01 +08:00
b021bbdc80 components/bt: Some errors in comment 2018-11-16 15:27:28 +08:00
c9fe4fa13e components/bt: Put function in isr into iram(backport 3.2) 2018-11-16 07:19:51 +00:00
96252c493a Merge branch 'bugfix/app_template_build_v3.2' into 'release/v3.2'
esp-idf-template app: some fixes for the updated template app  (backport v3.2)

See merge request idf/esp-idf!3700
2018-11-16 15:18:36 +08:00
007a4fcc4e tools: fix cmake build script for sdkconfig test 2018-11-16 02:48:35 +00:00
dbeb8ae02a cmake: fix the creation dummy main to avoid rebuilding 2018-11-16 02:48:35 +00:00
9921c8b91f ci: If there is no sdkconfig, we have to generate one 2018-11-16 02:48:35 +00:00
e16f65f4e6 Merge branch 'bugfix/tw27096_fix_lwip_mbox_free_crash_v3.2' into 'release/v3.2'
fix the crash caused by sys_mbox_free (backport v3.2)

See merge request idf/esp-idf!3676
2018-11-15 10:31:46 +08:00
fe0a5b41bf Merge branch 'bugfix/fix_memory_leak_for_v3.2' into 'release/v3.2'
Component/bt: fix memory leak in service change(backport v3.2)

See merge request idf/esp-idf!3685
2018-11-14 15:35:03 +08:00
1f7c54ae85 Component/bt: fix memory leak in service change 2018-11-12 19:41:19 +08:00
049bd9fe0a Merge branch 'bugfix/mesh_start_stop_v3.2' into 'release/v3.2'
mesh: update libs (backport3.2)

See merge request idf/esp-idf!3648
2018-11-12 15:59:14 +08:00
167fb50a22 Merge branch 'temp/release_v3_2_fastforward' into 'release/v3.2'
release v3.2 fastforward

See merge request idf/esp-idf!3678
2018-11-12 15:31:58 +08:00
5f3b532c8d lwip: fix crash caused by sys_mbox_free
Fix lwip crashed bug caused by sys_mbox_free()
2018-11-11 12:17:36 +08:00
841a6dcd9a mesh: update libs
1. fix ap_loss that occurs when the parent turns off the mesh function and becomes a normal WiFi with a different SSID.
2. add an event MESH_EVENT_NETWORK_STATE that contains information about whether there is a root in the current network.
3. modify the mechanism of mesh IE update.
4. fix a problem in the process of re-voting to select the root, the device that does not meet the conditions of being a root votes for itself.
5. fix an issue that occurs in esp_mesh_recv_toDS() when stopping the mesh.
6. when the user specifies a parent for the device, the device will set the authmode and password of its AP mode to the same value as the specified parent.
7. add two disconnected reason codes MESH_REASON_EMPTY_PASSWORD and MESH_REASON_PARENT_UNENCRYPTED.
2018-11-06 23:00:59 +08:00
307 changed files with 8188 additions and 3675 deletions

View File

@ -2,8 +2,7 @@ stages:
- build
- assign_test
- host_test
- unit_test
- integration_test
- target_test
- check
- deploy
- post_check
@ -114,19 +113,21 @@ build_template_app:
- build
variables:
BATCH_BUILD: "1"
IDF_CI_BUILD: "1"
only:
variables:
- $BOT_TRIGGER_WITH_LABEL == null
- $BOT_LABEL_BUILD
- $BOT_LABEL_REGULAR_TEST
script:
- git clone https://github.com/espressif/esp-idf-template.git
# Set the variable for 'esp-idf-template' testing
- ESP_IDF_TEMPLATE_GIT=${ESP_IDF_TEMPLATE_GIT:-"https://github.com/espressif/esp-idf-template.git"}
- git clone ${ESP_IDF_TEMPLATE_GIT}
- cd esp-idf-template
# Try to use the same branch name for esp-idf-template that we're
# using on esp-idf. If it doesn't exist then just stick to the default
# branch
- python $CHECKOUT_REF_SCRIPT esp-idf-template
- make defconfig
# Test debug build (default)
- make all V=1
# Now test release build
@ -180,13 +181,13 @@ build_ssc_02:
# If you want to add new build ssc jobs, please add it into dependencies of `assign_test` and `.test_template`
build_esp_idf_tests:
.build_esp_idf_unit_test_template: &build_esp_idf_unit_test_template
<<: *build_template
artifacts:
paths:
- tools/unit-test-app/output
- components/idf_test/unit_test/TestCaseAll.yml
- components/idf_test/unit_test/CIConfigs/*.yml
expire_in: 2 days
only:
variables:
@ -194,11 +195,30 @@ build_esp_idf_tests:
- $BOT_LABEL_BUILD
- $BOT_LABEL_UNIT_TEST
- $BOT_LABEL_REGULAR_TEST
build_esp_idf_tests_make:
<<: *build_esp_idf_unit_test_template
script:
- export PATH="$IDF_PATH/tools:$PATH"
- cd $CI_PROJECT_DIR/tools/unit-test-app
- export EXTRA_CFLAGS="-Werror -Werror=deprecated-declarations"
- export EXTRA_CXXFLAGS=${EXTRA_CFLAGS}
- cd $CI_PROJECT_DIR/tools/unit-test-app
- MAKEFLAGS= make help # make sure kconfig tools are built in single process
- make ut-clean-all-configs
- make ut-build-all-configs
- python tools/UnitTestParser.py
- if [ "$UNIT_TEST_BUILD_SYSTEM" == "make" ]; then exit 0; fi
# If Make, delete the CMake built artifacts
- rm -rf builds output sdkconfig
- rm -rf $CI_PROJECT_DIR/components/idf_test/unit_test/TestCaseAll.yml
- rm -rf $CI_PROJECT_DIR/components/idf_test/unit_test/CIConfigs/*.yml
build_esp_idf_tests_cmake:
<<: *build_esp_idf_unit_test_template
script:
- export PATH="$IDF_PATH/tools:$PATH"
- export EXTRA_CFLAGS="-Werror -Werror=deprecated-declarations"
- export EXTRA_CXXFLAGS=${EXTRA_CFLAGS}
- cd $CI_PROJECT_DIR/tools/unit-test-app
# Build with CMake first
- idf.py ut-clean-all-configs
- idf.py ut-build-all-configs
@ -207,14 +227,8 @@ build_esp_idf_tests:
- if [ "$UNIT_TEST_BUILD_SYSTEM" == "cmake" ]; then exit 0; fi
# If Make, delete the CMake built artifacts
- rm -rf builds output sdkconfig
- rm -rf components/idf_test/unit_test/TestCaseAll.yml
- rm -rf components/idf_test/unit_test/CIConfigs/*.yml
# Then build with Make
- cd $CI_PROJECT_DIR/tools/unit-test-app
- MAKEFLAGS= make help # make sure kconfig tools are built in single process
- make ut-clean-all-configs
- make ut-build-all-configs
- python tools/UnitTestParser.py
- rm -rf $CI_PROJECT_DIR/components/idf_test/unit_test/TestCaseAll.yml
- rm -rf $CI_PROJECT_DIR/components/idf_test/unit_test/CIConfigs/*.yml
.build_examples_make_template: &build_examples_make_template
<<: *build_template
@ -225,6 +239,7 @@ build_esp_idf_tests:
when: always
paths:
- build_examples/*/*/*/build/*.bin
- build_examples/*/*/*/sdkconfig
- build_examples/*/*/*/build/*.elf
- build_examples/*/*/*/build/*.map
- build_examples/*/*/*/build/download.config
@ -232,7 +247,6 @@ build_esp_idf_tests:
- $LOG_PATH
expire_in: 2 days
variables:
IDF_CI_BUILD: "1"
LOG_PATH: "$CI_PROJECT_DIR/log_examples_make"
only:
variables:
@ -257,6 +271,7 @@ build_esp_idf_tests:
when: always
paths:
- build_examples_cmake/*/*/*/build/*.bin
- build_examples_cmake/*/*/*/sdkconfig
- build_examples_cmake/*/*/*/build/*.elf
- build_examples_cmake/*/*/*/build/*.map
- build_examples_cmake/*/*/*/build/download.config
@ -264,7 +279,6 @@ build_esp_idf_tests:
- $LOG_PATH
expire_in: 2 days
variables:
IDF_CI_BUILD: "1"
LOG_PATH: "$CI_PROJECT_DIR/log_examples_cmake"
only:
variables:
@ -715,8 +729,11 @@ check_ut_cmake_make:
check_submodule_sync:
<<: *check_job_template
tags:
- github_sync
variables:
GIT_STRATEGY: clone
retry: 2
script:
# check if all submodules are correctly synced to public repostory
- git submodule update --init --recursive
@ -749,7 +766,8 @@ assign_test:
- build_ssc_00
- build_ssc_01
- build_ssc_02
- build_esp_idf_tests
- build_esp_idf_tests_make
- build_esp_idf_tests_cmake
variables:
TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw"
EXAMPLE_CONFIG_OUTPUT_PATH: "$CI_PROJECT_DIR/examples/test_configs"
@ -779,7 +797,7 @@ assign_test:
- python CIAssignTestCases.py -t $IDF_PATH/components/idf_test/integration_test -c $IDF_PATH/.gitlab-ci.yml -b $IDF_PATH/SSC/ssc_bin
.example_test_template: &example_test_template
stage: integration_test
stage: target_test
when: on_success
only:
refs:
@ -814,6 +832,8 @@ assign_test:
paths:
- $LOG_PATH
expire_in: 1 week
reports:
junit: $LOG_PATH/*/XUNIT_RESULT.xml
variables:
TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw"
TEST_CASE_PATH: "$CI_PROJECT_DIR/examples"
@ -833,10 +853,11 @@ assign_test:
.unit_test_template: &unit_test_template
<<: *example_test_template
stage: unit_test
stage: target_test
dependencies:
- assign_test
- build_esp_idf_tests
- build_esp_idf_tests_make
- build_esp_idf_tests_cmake
only:
refs:
- master
@ -855,7 +876,7 @@ assign_test:
ENV_FILE: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/EnvConfig.yml"
.test_template: &test_template
stage: integration_test
stage: target_test
when: on_success
only:
refs:
@ -942,7 +963,7 @@ example_test_002_01:
- ESP32
- Example_ShieldBox_Basic
example_test_003_01:
.example_test_003_01:
<<: *example_test_template
tags:
- ESP32
@ -1522,6 +1543,45 @@ UT_012_03:
- UT_T1_1
- 8Mpsram
UT_012_04:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T1_1
- 8Mpsram
UT_017_01:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T2_1
UT_017_02:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T2_1
UT_017_03:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T2_1
UT_017_04:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T2_1
- psram
UT_017_05:
<<: *unit_test_template
tags:
- ESP32_IDF
- UT_T2_1
- 8Mpsram
UT_601_01:
<<: *unit_test_template
tags:
@ -1678,6 +1738,18 @@ IT_006_05:
- ESP32_IDF
- SSC_T1_6
IT_006_06:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_6
IT_006_07:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_6
IT_007_01:
<<: *test_template
tags:
@ -1690,6 +1762,12 @@ IT_007_02:
- ESP32_IDF
- SSC_T1_7
IT_007_03:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_7
IT_008_01:
<<: *test_template
tags:
@ -1720,6 +1798,12 @@ IT_012_01:
- ESP32_IDF
- SSC_T1_9
IT_012_02:
<<: *test_template
tags:
- ESP32_IDF
- SSC_T1_9
IT_013_01:
<<: *test_template
tags:

View File

@ -145,8 +145,7 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
if (it->handle == handle) {
// must erase the partition before writing to it
assert(it->erased_size > 0 && "must erase the partition before writing to it");
if(it->wrote_size == 0 && size > 0 && data_bytes[0] != 0xE9) {
if (it->wrote_size == 0 && it->partial_bytes == 0 && size > 0 && data_bytes[0] != ESP_IMAGE_HEADER_MAGIC) {
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x", data_bytes[0]);
return ESP_ERR_OTA_VALIDATE_FAILED;
}

View File

@ -17,8 +17,7 @@ externalproject_add(bootloader
# TODO: support overriding the bootloader in COMPONENT_PATHS
SOURCE_DIR "${IDF_PATH}/components/bootloader/subproject"
BINARY_DIR "${bootloader_build_dir}"
CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH=${IDF_PATH} -DEXTRA_COMPONENT_DIRS=${COMPONENT_DIRS}
-DTESTS_ALL=0 -DTEST_COMPONENTS=""
CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH=${IDF_PATH}
INSTALL_COMMAND ""
BUILD_ALWAYS 1 # no easy way around this...
BUILD_BYPRODUCTS ${bootloader_binary_files}

View File

@ -111,4 +111,21 @@ esp_err_t bootloader_flash_erase_sector(size_t sector);
*/
esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size);
/* Cache MMU block size */
#define MMU_BLOCK_SIZE 0x00010000
/* Cache MMU address mask (MMU tables ignore bits which are zero) */
#define MMU_FLASH_MASK (~(MMU_BLOCK_SIZE - 1))
/**
* @brief Calculate the number of cache pages to map
* @param size size of data to map
* @param vaddr virtual address where data will be mapped
* @return number of cache MMU pages required to do the mapping
*/
static inline uint32_t bootloader_cache_pages_to_map(uint32_t size, uint32_t vaddr)
{
return (size + (vaddr - (vaddr & MMU_FLASH_MASK)) + MMU_BLOCK_SIZE - 1) / MMU_BLOCK_SIZE;
}
#endif

View File

@ -31,14 +31,14 @@ void bootloader_clock_configure()
/* Set CPU to 80MHz. Keep other clocks unmodified. */
int cpu_freq_mhz = 80;
/* On ESP32 rev 0, switching to 80MHz if clock was previously set to
/* On ESP32 rev 0, switching to 80/160 MHz if clock was previously set to
* 240 MHz may cause the chip to lock up (see section 3.5 of the errata
* document). For rev. 0, switch to 240 instead if it was chosen in
* menuconfig.
* document). For rev. 0, switch to 240 instead if it has been enabled
* previously.
*/
uint32_t chip_ver_reg = REG_READ(EFUSE_BLK0_RDATA3_REG);
if ((chip_ver_reg & EFUSE_RD_CHIP_VER_REV1_M) == 0 &&
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240) {
DPORT_REG_GET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL) == DPORT_CPUPERIOD_SEL_240) {
cpu_freq_mhz = 240;
}

View File

@ -91,8 +91,6 @@ static const char *TAG = "bootloader_flash";
*/
#define MMU_BLOCK0_VADDR 0x3f400000
#define MMU_BLOCK50_VADDR 0x3f720000
#define MMU_FLASH_MASK 0xffff0000
#define MMU_BLOCK_SIZE 0x00010000
static bool mapped;
@ -112,10 +110,11 @@ const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
}
uint32_t src_addr_aligned = src_addr & MMU_FLASH_MASK;
uint32_t count = (size + (src_addr - src_addr_aligned) + 0xffff) / MMU_BLOCK_SIZE;
uint32_t count = bootloader_cache_pages_to_map(size, src_addr);
Cache_Read_Disable(0);
Cache_Flush(0);
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d", src_addr_aligned, count );
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d size=%x src_addr=%x src_addr_aligned=%x",
src_addr & MMU_FLASH_MASK, count, size, src_addr, src_addr_aligned );
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count);
if (e != 0) {
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);

View File

@ -72,6 +72,7 @@ static void wdt_reset_check(void);
esp_err_t bootloader_init()
{
cpu_configure_region_protection();
cpu_init_memctl();
/* Sanity check that static RAM is after the stack */
#ifndef NDEBUG

View File

@ -389,7 +389,7 @@ static void unpack_load_app(const esp_image_metadata_t* data)
// Find DROM & IROM addresses, to configure cache mappings
for (int i = 0; i < data->image.segment_count; i++) {
const esp_image_segment_header_t *header = &data->segments[i];
if (header->load_addr >= SOC_IROM_LOW && header->load_addr < SOC_IROM_HIGH) {
if (header->load_addr >= SOC_DROM_LOW && header->load_addr < SOC_DROM_HIGH) {
if (drom_addr != 0) {
ESP_LOGE(TAG, MAP_ERR_MSG, "DROM");
} else {
@ -399,7 +399,7 @@ static void unpack_load_app(const esp_image_metadata_t* data)
drom_load_addr = header->load_addr;
drom_size = header->data_len;
}
if (header->load_addr >= SOC_DROM_LOW && header->load_addr < SOC_DROM_HIGH) {
if (header->load_addr >= SOC_IROM_LOW && header->load_addr < SOC_IROM_HIGH) {
if (irom_addr != 0) {
ESP_LOGE(TAG, MAP_ERR_MSG, "IROM");
} else {
@ -430,6 +430,7 @@ static void set_cache_and_start_app(
uint32_t irom_size,
uint32_t entry_addr)
{
int rc;
ESP_LOGD(TAG, "configure drom and irom and start");
Cache_Read_Disable( 0 );
Cache_Flush( 0 );
@ -441,20 +442,34 @@ static void set_cache_and_start_app(
DPORT_PRO_FLASH_MMU_TABLE[i] = DPORT_FLASH_MMU_TABLE_INVALID_VAL;
}
uint32_t drom_page_count = (drom_size + 64*1024 - 1) / (64*1024); // round up to 64k
ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d", drom_addr & 0xffff0000, drom_load_addr & 0xffff0000, drom_size, drom_page_count );
int rc = cache_flash_mmu_set( 0, 0, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, 64, drom_page_count );
ESP_LOGV(TAG, "rc=%d", rc );
rc = cache_flash_mmu_set( 1, 0, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, 64, drom_page_count );
ESP_LOGV(TAG, "rc=%d", rc );
uint32_t irom_page_count = (irom_size + 64*1024 - 1) / (64*1024); // round up to 64k
ESP_LOGV(TAG, "i mmu set paddr=%08x vaddr=%08x size=%d n=%d", irom_addr & 0xffff0000, irom_load_addr & 0xffff0000, irom_size, irom_page_count );
rc = cache_flash_mmu_set( 0, 0, irom_load_addr & 0xffff0000, irom_addr & 0xffff0000, 64, irom_page_count );
ESP_LOGV(TAG, "rc=%d", rc );
rc = cache_flash_mmu_set( 1, 0, irom_load_addr & 0xffff0000, irom_addr & 0xffff0000, 64, irom_page_count );
ESP_LOGV(TAG, "rc=%d", rc );
DPORT_REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG, (DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) | (DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 | DPORT_PRO_CACHE_MASK_DRAM1 );
DPORT_REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG, (DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) | (DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 | DPORT_APP_CACHE_MASK_DRAM1 );
uint32_t drom_load_addr_aligned = drom_load_addr & MMU_FLASH_MASK;
uint32_t drom_page_count = bootloader_cache_pages_to_map(drom_size, drom_load_addr);
ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d",
drom_addr & MMU_FLASH_MASK, drom_load_addr_aligned, drom_size, drom_page_count);
rc = cache_flash_mmu_set(0, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count);
ESP_LOGV(TAG, "rc=%d", rc);
rc = cache_flash_mmu_set(1, 0, drom_load_addr_aligned, drom_addr & MMU_FLASH_MASK, 64, drom_page_count);
ESP_LOGV(TAG, "rc=%d", rc);
uint32_t irom_load_addr_aligned = irom_load_addr & MMU_FLASH_MASK;
uint32_t irom_page_count = bootloader_cache_pages_to_map(irom_size, irom_load_addr);
ESP_LOGV(TAG, "i mmu set paddr=%08x vaddr=%08x size=%d n=%d",
irom_addr & MMU_FLASH_MASK, irom_load_addr_aligned, irom_size, irom_page_count);
rc = cache_flash_mmu_set(0, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count);
ESP_LOGV(TAG, "rc=%d", rc);
rc = cache_flash_mmu_set(1, 0, irom_load_addr_aligned, irom_addr & MMU_FLASH_MASK, 64, irom_page_count);
ESP_LOGV(TAG, "rc=%d", rc);
DPORT_REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG,
(DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) |
(DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 |
DPORT_PRO_CACHE_MASK_DRAM1 );
DPORT_REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG,
(DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) |
(DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 |
DPORT_APP_CACHE_MASK_DRAM1 );
Cache_Read_Enable( 0 );
// Application will need to do Cache_Flush(1) and Cache_Read_Enable(1)

View File

@ -135,7 +135,6 @@ config BTDM_CONTROLLER_MODEM_SLEEP
default y
help
Enable/disable bluetooth controller low power mode.
Note that currently there is problem in the combination use of bluetooth modem sleep and Dynamic Frequency Scaling(DFS). So do not enable DFS if bluetooth modem sleep is in use.
choice BTDM_MODEM_SLEEP_MODE
prompt "Bluetooth Modem sleep mode"
@ -146,11 +145,13 @@ choice BTDM_MODEM_SLEEP_MODE
config BTDM_MODEM_SLEEP_MODE_ORIG
bool "ORIG Mode(sleep with low power clock)"
help
ORIG mode is a deep sleep mode that can be used for dual mode controller. In this mode, bluetooth controller sleeps between BR/EDR frames and BLE events. A low power clock is used to maintain bluetooth reference clock.
ORIG mode is a bluetooth sleep mode that can be used for dual mode controller. In this mode, bluetooth controller
sleeps between BR/EDR frames and BLE events. A low power clock is used to maintain bluetooth reference clock.
config BTDM_MODEM_SLEEP_MODE_EVED
bool "EVED Mode "
bool "EVED Mode(For internal test only)"
help
This mode is for BLE only.
EVED mode is for BLE only and is only for internal test. Do not use it for production. this mode is not compatible
with DFS nor light sleep
endchoice
choice BTDM_LOW_POWER_CLOCK
@ -161,6 +162,10 @@ choice BTDM_LOW_POWER_CLOCK
config BTDM_LPCLK_SEL_MAIN_XTAL
bool "Main crystal"
help
Main crystal can be used as low power clock for bluetooth modem sleep. If this option is selected, bluetooth
modem sleep can work under Dynamic Frequency Scaling(DFS) enabled, but cannot work when light sleep is enabled.
Main crystal has a relatively better performance than other bluetooth low power clock sources.
config BTDM_LPCLK_SEL_EXT_32K_XTAL
bool "External 32kHz crystal"
depends on ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
@ -238,6 +243,39 @@ config MESH_DUPLICATE_SCAN_CACHE_SIZE
Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh.
When the maximum amount of device in the filter is reached, the cache will be refreshed.
config BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED
bool "BLE adv report flow control supported"
depends on (BTDM_CONTROLLER_MODE_BTDM || BTDM_CONTROLLER_MODE_BLE_ONLY)
default y
help
The function is mainly used to enable flow control for advertising reports. When it is enabled,
advertising reports will be discarded by the controller if the number of unprocessed advertising
reports exceeds the size of BLE adv report flow control.
config BLE_ADV_REPORT_FLOW_CONTROL_NUM
int "BLE adv report flow control number"
depends on BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED
range 50 1000
default 100
help
The number of unprocessed advertising report that Bluedroid can save.If you set
`BLE_ADV_REPORT_FLOW_CONTROL_NUM` to a small value, this may cause adv packets lost.
If you set `BLE_ADV_REPORT_FLOW_CONTROL_NUM` to a large value, Bluedroid may cache a
lot of adv packets and this may cause system memory run out. For example, if you set
it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set
`BLE_ADV_REPORT_FLOW_CONTROL_NUM` according to your system free memory and handle adv
packets as fast as possible, otherwise it will cause adv packets lost.
config BLE_ADV_REPORT_DISCARD_THRSHOLD
int "BLE adv lost event threshold value"
depends on BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED
range 1 1000
default 20
help
When adv report flow control is enabled, The ADV lost event will be generated when the number
of ADV packets lost in the controller reaches this threshold. It is better to set a larger value.
If you set `BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it
may cause adv packets lost more.
endmenu
@ -1180,6 +1218,15 @@ config SMP_ENABLE
depends on BLUEDROID_ENABLED
default CLASSIC_BT_ENABLED || BLE_SMP_ENABLE
config BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY
bool "Report adv data and scan response individually when BLE active scan"
depends on BLUEDROID_ENABLED && (BTDM_CONTROLLER_MODE_BTDM || BTDM_CONTROLLER_MODE_BLE_ONLY)
default n
help
Originally, when doing BLE active scan, Bluedroid will not report adv to application layer
until receive scan response. This option is used to disable the behavior. When enable this option,
Bluedroid will report adv data or scan response to application layer immediately.
# Memory reserved at start of DRAM for Bluetooth stack
config BT_RESERVE_DRAM
hex

View File

@ -449,6 +449,69 @@ esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_d
}
esp_err_t esp_ble_gap_add_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info)
{
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
if (!device_info){
return ESP_ERR_INVALID_SIZE;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST;
arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_ADD;
arg.update_duplicate_exceptional_list.info_type = type;
memcpy(arg.update_duplicate_exceptional_list.device_info, device_info, sizeof(esp_bd_addr_t));
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gap_remove_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info)
{
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
if (!device_info){
return ESP_ERR_INVALID_SIZE;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST;
arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_REMOVE;
arg.update_duplicate_exceptional_list.info_type = type;
memcpy(arg.update_duplicate_exceptional_list.device_info, device_info, sizeof(esp_bd_addr_t));
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_ble_gap_clean_duplicate_scan_exceptional_list(esp_duplicate_scan_exceptional_list_type_t list_type)
{
btc_msg_t msg;
btc_ble_gap_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST;
arg.update_duplicate_exceptional_list.subcode = ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_CLEAN;
arg.update_duplicate_exceptional_list.info_type = list_type;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#if (SMP_INCLUDED == TRUE)
esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type,
void *value, uint8_t len)

View File

@ -161,6 +161,7 @@ typedef enum {
ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT, /*!< When get the bond device list complete, the event comes */
ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT, /*!< When read the rssi complete, the event comes */
ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT, /*!< When add or remove whitelist complete, the event comes */
ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT, /*!< When update duplicate exceptional list complete, the event comes */
ESP_GAP_BLE_EVT_MAX,
} esp_gap_ble_cb_event_t;
/// This is the old name, just for backwards compatibility
@ -286,7 +287,7 @@ typedef struct {
esp_ble_adv_type_t adv_type; /*!< Advertising type */
esp_ble_addr_type_t own_addr_type; /*!< Owner bluetooth device address type */
esp_bd_addr_t peer_addr; /*!< Peer device bluetooth device address */
esp_ble_addr_type_t peer_addr_type; /*!< Peer device bluetooth device address type */
esp_ble_addr_type_t peer_addr_type; /*!< Peer device bluetooth device address type, only support public address type and random address type */
esp_ble_adv_channel_t channel_map; /*!< Advertising channel map */
esp_ble_adv_filter_t adv_filter_policy; /*!< Advertising filter policy */
} esp_ble_adv_params_t;
@ -303,9 +304,9 @@ typedef struct {
Value of 0xFFFF indicates no specific minimum.
Values not defined above are reserved for future use.*/
int max_interval; /*!< Advertising data show slave preferred connection max interval.
int max_interval; /*!< Advertising data show slave preferred connection max interval.
The connection interval in the following manner:
connIntervalmax = Conn_Interval_Max * 1.25 ms
connIntervalmax = Conn_Interval_Max * 1.25 ms
Conn_Interval_Max range: 0x0006 to 0x0C80
Conn_Interval_Max shall be equal to or greater than the Conn_Interval_Min.
Value of 0xFFFF indicates no specific maximum.
@ -366,8 +367,8 @@ typedef struct {
Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
Time = N * 0.625 msec
Time Range: 2.5 msec to 10240 msec */
esp_ble_scan_duplicate_t scan_duplicate; /*!< The Scan_Duplicates parameter controls whether the Link Layer should filter out
duplicate advertising reports (BLE_SCAN_DUPLICATE_ENABLE) to the Host, or if the Link Layer should generate
esp_ble_scan_duplicate_t scan_duplicate; /*!< The Scan_Duplicates parameter controls whether the Link Layer should filter out
duplicate advertising reports (BLE_SCAN_DUPLICATE_ENABLE) to the Host, or if the Link Layer should generate
advertising reports for each packet received */
} esp_ble_scan_params_t;
@ -552,6 +553,7 @@ typedef enum {
ESP_GAP_SEARCH_DISC_CMPL_EVT = 4, /*!< Discovery complete. */
ESP_GAP_SEARCH_DI_DISC_CMPL_EVT = 5, /*!< Discovery complete. */
ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT = 6, /*!< Search cancelled */
ESP_GAP_SEARCH_INQ_DISCARD_NUM_EVT = 7, /*!< The number of pkt discarded by flow control */
} esp_gap_search_evt_t;
/**
@ -570,6 +572,28 @@ typedef enum{
ESP_BLE_WHITELIST_REMOVE = 0X00, /*!< remove mac from whitelist */
ESP_BLE_WHITELIST_ADD = 0X01, /*!< add address to whitelist */
}esp_ble_wl_opration_t;
typedef enum {
ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_ADD = 0, /*!< Add device info into duplicate scan exceptional list */
ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_REMOVE, /*!< Remove device info from duplicate scan exceptional list */
ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_CLEAN, /*!< Clean duplicate scan exceptional list */
} esp_bt_duplicate_exceptional_subcode_type_t;
#define BLE_BIT(n) (1UL<<(n))
typedef enum {
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_ADV_ADDR = 0, /*!< BLE advertising address , device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST */
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID, /*!< BLE mesh link ID, it is for BLE mesh, device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST */
} esp_ble_duplicate_exceptional_info_type_t;
typedef enum {
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST = BLE_BIT(0), /*!< duplicate scan exceptional addr list */
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST = BLE_BIT(1), /*!< duplicate scan exceptional mesh link ID list */
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ALL_LIST = (BLE_BIT(0) | BLE_BIT(1)), /*!< duplicate scan exceptional all list */
} esp_duplicate_scan_exceptional_list_type_t;
typedef uint8_t esp_duplicate_info_t[ESP_BD_ADDR_LEN];
/**
* @brief Gap callback parameters union
*/
@ -607,6 +631,7 @@ typedef union {
int num_resps; /*!< Scan result number */
uint8_t adv_data_len; /*!< Adv data length */
uint8_t scan_rsp_len; /*!< Scan response length */
uint32_t num_dis; /*!< The number of discard packets */
} scan_rst; /*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */
/**
* @brief ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT
@ -715,6 +740,15 @@ typedef union {
esp_bt_status_t status; /*!< Indicate the add or remove whitelist operation success status */
esp_ble_wl_opration_t wl_opration; /*!< The value is ESP_BLE_WHITELIST_ADD if add address to whitelist operation success, ESP_BLE_WHITELIST_REMOVE if remove address from the whitelist operation success */
} update_whitelist_cmpl; /*!< Event parameter of ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT
*/
struct ble_update_duplicate_exceptional_list_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate update duplicate scan exceptional list operation success status */
uint8_t subcode; /*!< Define in esp_bt_duplicate_exceptional_subcode_type_t */
uint16_t length; /*!< The length of device_info */
esp_duplicate_info_t device_info; /*!< device information, when subcode is ESP_BLE_DUPLICATE_EXCEPTIONAL_LIST_CLEAN, the value is invalid */
} update_duplicate_exceptional_list_cmpl; /*!< Event parameter of ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT */
} esp_ble_gap_cb_param_t;
/**
@ -962,8 +996,7 @@ esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t
* @param[in] type - finding ADV data type
* @param[out] length - return the length of ADV data not including type
*
* @return - ESP_OK : success
* - other : failed
* @return pointer of ADV data
*
*/
uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length);
@ -1008,6 +1041,43 @@ esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_d
*/
esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr);
/**
* @brief This function is called to add a device info into the duplicate scan exceptional list.
*
*
* @param[in] type: device info type, it is defined in esp_ble_duplicate_exceptional_info_type_t
* @param[in] device_info: the device information.
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_ble_gap_add_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info);
/**
* @brief This function is called to remove a device info from the duplicate scan exceptional list.
*
*
* @param[in] type: device info type, it is defined in esp_ble_duplicate_exceptional_info_type_t
* @param[in] device_info: the device information.
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_ble_gap_remove_duplicate_scan_exceptional_device(esp_ble_duplicate_exceptional_info_type_t type, esp_duplicate_info_t device_info);
/**
* @brief This function is called to clean the duplicate scan exceptional list.
* This API will delete all device information in the duplicate scan exceptional list.
*
*
* @param[in] list_type: duplicate scan exceptional list type, the value can be one or more of esp_duplicate_scan_exceptional_list_type_t.
*
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_ble_gap_clean_duplicate_scan_exceptional_list(esp_duplicate_scan_exceptional_list_type_t list_type);
#if (SMP_INCLUDED == TRUE)
/**
* @brief Set a GAP security parameter value. Overrides the default value.

View File

@ -251,9 +251,9 @@ typedef union {
} esp_hf_client_cb_param_t;
/**
* @brief HFP client incoming data callback function, the callback is useful in case of
* @brief HFP client incoming data callback function, the callback is useful in case of
* Voice Over HCI.
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
* buffer is allocated inside bluetooth protocol stack and will be released after
* invoke of the callback is finished.
* @param[in] len : size(in bytes) in buf
@ -261,13 +261,13 @@ typedef union {
typedef void (* esp_hf_client_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
/**
* @brief HFP client outgoing data callback function, the callback is useful in case of
* Voice Over HCI. Once audio connection is set up and the application layer has
* prepared data to send, the lower layer will call this function to read data
* @brief HFP client outgoing data callback function, the callback is useful in case of
* Voice Over HCI. Once audio connection is set up and the application layer has
* prepared data to send, the lower layer will call this function to read data
* and then send. This callback is supposed to be implemented as non-blocking,
* and if data is not enough, return value 0 is supposed.
*
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
*
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
* buffer is allocated inside bluetooth protocol stack and will be released after
* invoke of the callback is finished.
* @param[in] len : size(in bytes) in buf
@ -326,7 +326,7 @@ esp_err_t esp_hf_client_deinit(void);
/**
*
* @brief Connect to remote bluetooth HFP audio gateway(AG) device, must after esp_a2d_hf_client_init()
* @brief Connect to remote bluetooth HFP audio gateway(AG) device, must after esp_hf_client_init()
*
* @param[in] remote_bda: remote bluetooth device address
*
@ -606,7 +606,7 @@ void esp_hf_client_outgoing_data_ready(void);
/**
* @brief Initialize the down sampling converter. This is a utility function that can
* only be used in the case that Voice Over HCI is enabled.
* only be used in the case that Voice Over HCI is enabled.
*
* @param[in] src_sps: original samples per second(source audio data, i.e. 48000, 32000,
* 16000, 44100, 22050, 11025)

View File

@ -190,8 +190,7 @@ esp_err_t esp_spp_register_callback(esp_spp_cb_t callback);
/**
* @brief This function is called to init SPP.
*
* @param[in] mode: Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_CB.
* Now only supports ESP_SPP_MODE_CB mode, we will continue to update.
* @param[in] mode: Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS.
*
* @return
* - ESP_OK: success

View File

@ -127,6 +127,7 @@ static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
#endif ///SMP_INCLUDED == TRUE
static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
static void bta_dm_observe_cmpl_cb(void *p_result);
static void bta_dm_observe_discard_cb (uint32_t num_dis);
static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle);
extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8 *p_uuid128);
static void bta_dm_disable_timer_cback(TIMER_LIST_ENT *p_tle);
@ -2666,9 +2667,7 @@ static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NA
}
}
#if (BT_SSP_INCLUDED == TRUE)
/*******************************************************************************
**
** Function bta_dm_pinname_cback
@ -2725,6 +2724,7 @@ static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NA
bta_dm_cb.p_sec_cback(event, &sec_event);
}
}
#endif /// BT_SSP_INCLUDED == TRUE
/*******************************************************************************
**
@ -2744,18 +2744,6 @@ static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_
return BTM_NOT_AUTHORIZED;
}
/* If the device name is not known, save bdaddr and devclass and initiate a name request */
if (bd_name[0] == 0) {
bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
return BTM_CMD_STARTED;
}
APPL_TRACE_WARNING(" bta_dm_pin_cback() -> Failed to start Remote Name Request ");
}
bdcpy(sec_event.pin_req.bd_addr, bd_addr);
BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
@ -4271,6 +4259,28 @@ static void bta_dm_observe_cmpl_cb (void *p_result)
}
}
/*******************************************************************************
**
** Function bta_dm_observe_discard_cb
**
** Description Callback for BLE Observe lost
**
**
** Returns void
**
*******************************************************************************/
static void bta_dm_observe_discard_cb (uint32_t num_dis)
{
tBTA_DM_SEARCH data;
APPL_TRACE_DEBUG("bta_dm_observe_discard_cb");
data.inq_dis.num_dis = num_dis;
if (bta_dm_search_cb.p_scan_cback) {
bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_DISCARD_NUM_EVT, &data);
}
}
#if (SMP_INCLUDED == TRUE)
/*******************************************************************************
**
@ -4475,7 +4485,8 @@ void bta_dm_add_ble_device (tBTA_DM_MSG *p_data)
{
if (!BTM_SecAddBleDevice (p_data->add_ble_device.bd_addr, NULL,
p_data->add_ble_device.dev_type ,
p_data->add_ble_device.addr_type)) {
p_data->add_ble_device.addr_type,
p_data->add_ble_device.auth_mode)) {
APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Device for device %08x%04x",
(p_data->add_ble_device.bd_addr[0] << 24) + (p_data->add_ble_device.bd_addr[1] << 16) + \
(p_data->add_ble_device.bd_addr[2] << 8) + p_data->add_ble_device.bd_addr[3],
@ -4801,7 +4812,7 @@ void bta_dm_ble_scan (tBTA_DM_MSG *p_data)
bta_dm_search_cb.p_scan_cback = p_data->ble_scan.p_cback;
if ((status = BTM_BleScan(TRUE, p_data->ble_scan.duration,
bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb, bta_dm_observe_discard_cb)) != BTM_CMD_STARTED) {
APPL_TRACE_WARNING(" %s start scan failed. status=0x%x\n", __FUNCTION__, status);
}
@ -4811,7 +4822,7 @@ void bta_dm_ble_scan (tBTA_DM_MSG *p_data)
}
} else {
bta_dm_search_cb.p_scan_cback = NULL;
status = BTM_BleScan(FALSE, 0, NULL, NULL);
status = BTM_BleScan(FALSE, 0, NULL, NULL, NULL);
if (status != BTM_CMD_STARTED){
APPL_TRACE_WARNING(" %s stop scan failed, status=0x%x\n", __FUNCTION__, status);
@ -4868,6 +4879,22 @@ void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data)
}
}
/*******************************************************************************
**
** Function bta_dm_ble_update_duplicate_exceptional_list
**
** Description This function is to update duplicate scan exceptional list
**
**
*******************************************************************************/
void bta_dm_ble_update_duplicate_exceptional_list(tBTA_DM_MSG *p_data)
{
BTM_UpdateBleDuplicateExceptionalList(p_data->ble_duplicate_exceptional_list.subcode,
p_data->ble_duplicate_exceptional_list.type,
p_data->ble_duplicate_exceptional_list.device_info,
p_data->ble_duplicate_exceptional_list.exceptional_list_cb);
}
/*******************************************************************************
**
** Function bta_dm_ble_set_adv_config

View File

@ -797,12 +797,13 @@ void BTA_DmAddBleKey (BD_ADDR bd_addr, tBTA_LE_KEY_VALUE *p_le_key, tBTA_LE_KEY_
**
** Parameters: bd_addr - BD address of the peer
** dev_type - Remote device's device type.
** auth_mode - auth mode
** addr_type - LE device address type.
**
** Returns void
**
*******************************************************************************/
void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type, tBT_DEVICE_TYPE dev_type)
void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type, int auth_mode, tBT_DEVICE_TYPE dev_type)
{
tBTA_DM_API_ADD_BLE_DEVICE *p_msg;
@ -812,6 +813,7 @@ void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type, tBT_DEVICE_TY
p_msg->hdr.event = BTA_DM_API_ADD_BLEDEVICE_EVT;
bdcpy(p_msg->bd_addr, bd_addr);
p_msg->addr_type = addr_type;
p_msg->auth_mode = auth_mode;
p_msg->dev_type = dev_type;
bta_sys_sendmsg(p_msg);
@ -1256,6 +1258,34 @@ void BTA_DmBleSetScanRspRaw (UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len,
}
}
/*******************************************************************************
**
** Function BTA_DmUpdateDuplicateExceptionalList
**
** Description This function is called to update duplicate scan exceptional list
**
** Parameters subcode : add, remove or clean duplicate scan exceptional list.
** type : device info type.
** device_info: device info
** p_update_duplicate_ignore_list_cback : update complete callback.
**
** Returns None
**
*******************************************************************************/
void BTA_DmUpdateDuplicateExceptionalList(UINT8 subcode, UINT32 type, BD_ADDR device_info, tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK p_update_duplicate_exceptional_list_cback)
{
tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST *p_msg;
if ((p_msg = (tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST *)osi_malloc(sizeof(tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST))) != NULL) {
p_msg->hdr.event = BTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_EVT;
p_msg->subcode = subcode;
p_msg->type = type;
p_msg->exceptional_list_cb = p_update_duplicate_exceptional_list_cback;
memcpy(p_msg->device_info, device_info, sizeof(BD_ADDR));
bta_sys_sendmsg(p_msg);
}
}
/*******************************************************************************
**
** Function BTA_DmBleSetStorageParams

View File

@ -157,6 +157,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
bta_dm_update_white_list, /* BTA_DM_API_UPDATE_WHITE_LIST_EVT */
bta_dm_ble_read_adv_tx_power, /* BTA_DM_API_BLE_READ_ADV_TX_POWER_EVT */
bta_dm_ble_read_rssi, /* BTA_DM_API_BLE_READ_RSSI_EVT */
bta_dm_ble_update_duplicate_exceptional_list,/* BTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_EVT */
};

View File

@ -155,6 +155,7 @@ enum {
BTA_DM_API_UPDATE_WHITE_LIST_EVT,
BTA_DM_API_BLE_READ_ADV_TX_POWER_EVT,
BTA_DM_API_BLE_READ_RSSI_EVT,
BTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_EVT,
BTA_DM_MAX_EVT
};
@ -193,6 +194,14 @@ typedef struct {
tBTA_ADD_WHITELIST_CBACK *add_wl_cb;
}tBTA_DM_API_UPDATE_WHITE_LIST;
typedef struct {
BT_HDR hdr;
UINT8 subcode;
UINT32 type;
BD_ADDR device_info;
tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK *exceptional_list_cb;
}tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST;
typedef struct {
BT_HDR hdr;
tBTA_CMPL_CB *read_tx_power_cb;
@ -445,6 +454,7 @@ typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
tBT_DEVICE_TYPE dev_type ;
UINT32 auth_mode;
tBLE_ADDR_TYPE addr_type;
} tBTA_DM_API_ADD_BLE_DEVICE;
@ -847,6 +857,7 @@ typedef union {
tBTA_DM_API_TRACK_ADVERTISER ble_track_advert;
tBTA_DM_API_ENERGY_INFO ble_energy_info;
tBTA_DM_API_BLE_DISCONNECT ble_disconnect;
tBTA_DM_API_UPDATE_DUPLICATE_EXCEPTIONAL_LIST ble_duplicate_exceptional_list;
#endif
tBTA_DM_API_REMOVE_ACL remove_acl;
@ -1242,7 +1253,7 @@ extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_update_duplicate_exceptional_list(tBTA_DM_MSG *p_data);
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
extern void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data);
extern void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data);

View File

@ -932,6 +932,9 @@ static void bta_gatts_send_request_cback (UINT16 conn_id,
cb_data.req_data.trans_id = trans_id;
cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data;
if(req_type == BTA_GATTS_CONF_EVT) {
cb_data.req_data.handle = p_data->handle;
}
(*p_rcb->p_cback)(req_type, &cb_data);
} else {
APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if);

View File

@ -399,6 +399,8 @@ typedef struct {
UINT8 tx_power;
} tBTA_BLE_ADV_DATA;
typedef void (tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTA_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info);
typedef void (tBTA_SET_ADV_DATA_CMPL_CBACK) (tBTA_STATUS status);
typedef tBTM_START_ADV_CMPL_CBACK tBTA_START_ADV_CMPL_CBACK;
@ -1022,6 +1024,7 @@ typedef struct {
#define BTA_DM_DISC_CMPL_EVT 4 /* Discovery complete. */
#define BTA_DM_DI_DISC_CMPL_EVT 5 /* Discovery complete. */
#define BTA_DM_SEARCH_CANCEL_CMPL_EVT 6 /* Search cancelled */
#define BTA_DM_INQ_DISCARD_NUM_EVT 7 /* The number of inquiry discarded packets */
typedef UINT8 tBTA_DM_SEARCH_EVT;
@ -1053,6 +1056,11 @@ typedef struct {
UINT8 num_resps; /* Number of inquiry responses. */
} tBTA_DM_INQ_CMPL;
/* Structure associated with BTA_DM_INQ_DISCARD_NUM_EVT */
typedef struct {
UINT32 num_dis; /* The number of inquiry discarded packets. */
} tBTA_DM_INQ_DISCARD;
/* Structure associated with BTA_DM_DI_DISC_CMPL_EVT */
typedef struct {
BD_ADDR bd_addr; /* BD address peer device. */
@ -1090,6 +1098,7 @@ typedef union {
tBTA_DM_DISC_RES disc_res; /* Discovery result for a peer device. */
tBTA_DM_DISC_BLE_RES disc_ble_res; /* Discovery result for GATT based service */
tBTA_DM_DI_DISC_CMPL di_disc; /* DI discovery result for a peer device */
tBTA_DM_INQ_DISCARD inq_dis; /* the discarded packets information of inquiry */
} tBTA_DM_SEARCH;
/* Structure of search callback event and structures */
@ -1870,12 +1879,13 @@ extern void BTA_DmBleConfirmReply(BD_ADDR bd_addr, BOOLEAN accept);
**
** Parameters: bd_addr - BD address of the peer
** dev_type - Remote device's device type.
** auth_mode - auth mode
** addr_type - LE device address type.
**
** Returns void
**
*******************************************************************************/
extern void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type,
extern void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type, int auth_mode,
tBT_DEVICE_TYPE dev_type);
@ -2236,6 +2246,24 @@ extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask,
extern void BTA_DmBleSetScanRspRaw (UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len,
tBTA_SET_ADV_DATA_CMPL_CBACK *p_scan_rsp_data_cback);
/*******************************************************************************
**
** Function BTA_DmUpdateDuplicateExceptionalList
**
** Description This function is called to update duplicate scan exceptional list
**
** Parameters subcode : add, remove or clean duplicate scan exceptional list.
** type : device info type.
** device_info: device info
** p_update_duplicate_ignore_list_cback : update complete callback.
**
** Returns None
**
*******************************************************************************/
extern void BTA_DmUpdateDuplicateExceptionalList(UINT8 subcode, UINT32 type,
BD_ADDR device_info,
tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK p_update_duplicate_exceptional_list_cback);
/*******************************************************************************
**
** Function BTA_DmBleBroadcast

View File

@ -553,6 +553,91 @@ bt_status_t btc_storage_remove_ble_dev_type(bt_bdaddr_t *remote_bd_addr, bool fl
return ret;
}
static bt_status_t _btc_storage_set_ble_dev_auth_mode(bt_bdaddr_t *remote_bd_addr, uint8_t auth_mode, bool flush)
{
int ret;
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t));
ret = btc_config_set_int(bdstr, BTC_BLE_STORAGE_LE_AUTH_MODE_STR, (int)auth_mode);
if (ret == false) {
return BT_STATUS_FAIL;
}
if (flush) {
_btc_storage_save();
}
return BT_STATUS_SUCCESS;
}
bt_status_t btc_storage_set_ble_dev_auth_mode(bt_bdaddr_t *remote_bd_addr, uint8_t auth_mode, bool flush)
{
bt_status_t ret;
btc_config_lock();
ret = _btc_storage_set_ble_dev_auth_mode(remote_bd_addr, auth_mode, flush);
btc_config_unlock();
return ret;
}
static bt_status_t _btc_storage_get_ble_dev_auth_mode(bt_bdaddr_t *remote_bd_addr, int* auth_mode)
{
bdstr_t bdstr;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
int ret = btc_config_get_int(bdstr, BTC_BLE_STORAGE_LE_AUTH_MODE_STR, auth_mode);
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
bt_status_t btc_storage_get_ble_dev_auth_mode(bt_bdaddr_t *remote_bd_addr, int* auth_mode)
{
bt_status_t ret;
btc_config_lock();
ret = _btc_storage_get_ble_dev_auth_mode(remote_bd_addr, auth_mode);
btc_config_unlock();
return ret;
}
static bt_status_t _btc_storage_remove_ble_dev_auth_mode(bt_bdaddr_t *remote_bd_addr, bool flush)
{
bool ret = true;
bdstr_t bdstr;
uint32_t auth_mode = 0;
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
ret = btc_config_get_int(bdstr, BTC_BLE_STORAGE_LE_AUTH_MODE_STR, (int *)&auth_mode);
if (ret == false) {
//cannot find the key, just return SUCCESS, indicate already removed
return BT_STATUS_SUCCESS;
}
ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_AUTH_MODE_STR);
if (ret == false) {
return BT_STATUS_FAIL;
}
if (flush) {
_btc_storage_save();
}
return BT_STATUS_SUCCESS;
}
bt_status_t btc_storage_remove_ble_dev_auth_mode(bt_bdaddr_t *remote_bd_addr, bool flush)
{
bt_status_t ret;
btc_config_lock();
ret = _btc_storage_remove_ble_dev_auth_mode(remote_bd_addr, flush);
btc_config_unlock();
return ret;
}
static bt_status_t _btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type, bool flush)
{
int ret;
@ -657,7 +742,11 @@ static void _btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bd
bdcpy(bta_bd_addr, bd_addr.address);
if (!*device_added) {
BTA_DmAddBleDevice(bta_bd_addr, addr_type, BT_DEVICE_TYPE_BLE);
int auth_mode = 0;
if(_btc_storage_get_ble_dev_auth_mode(&bd_addr, &auth_mode) != BT_STATUS_SUCCESS) {
BTC_TRACE_WARNING("%s Failed to get auth mode from flash, please erase flash and download the firmware again", __func__);
}
BTA_DmAddBleDevice(bta_bd_addr, addr_type, auth_mode, BT_DEVICE_TYPE_BLE);
*device_added = true;
}

View File

@ -176,6 +176,7 @@ static void btc_dm_remove_ble_bonding_keys(void)
bdcpy(bd_addr.address, pairing_cb.bd_addr);
btc_storage_remove_remote_addr_type(&bd_addr, false);
btc_storage_remove_ble_dev_auth_mode(&bd_addr, false);
btc_storage_remove_ble_dev_type(&bd_addr, false);
btc_storage_remove_ble_bonding_keys(&bd_addr);
}
@ -261,9 +262,14 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
BTC_TRACE_DEBUG ("%s, - pairing_cb.bd_addr: %08x%04x", __func__,
(pairing_cb.bd_addr[0] << 24) + (pairing_cb.bd_addr[1] << 16) + (pairing_cb.bd_addr[2] << 8) + pairing_cb.bd_addr[3],
(pairing_cb.bd_addr[4] << 8) + pairing_cb.bd_addr[5]);
// Check if need to save BLE keys
if((p_auth_cmpl->auth_mode & SMP_AUTH_GEN_BOND) == 0) {
return;
}
if (btc_storage_get_remote_addr_type(&bdaddr, &addr_type) != BT_STATUS_SUCCESS) {
btc_storage_set_remote_addr_type(&bdaddr, p_auth_cmpl->addr_type, true);
}
btc_storage_set_ble_dev_auth_mode(&bdaddr, p_auth_cmpl->auth_mode, true);
btc_dm_save_ble_bonding_keys();
} else {
/*Map the HCI fail reason to bt status */
@ -638,6 +644,7 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
//remove the bonded key in the config and nvs flash.
btc_storage_remove_ble_dev_type(&bd_addr, false);
btc_storage_remove_remote_addr_type(&bd_addr, false);
btc_storage_remove_ble_dev_auth_mode(&bd_addr, false);
param.remove_bond_dev_cmpl.status = btc_storage_remove_ble_bonding_keys(&bd_addr);
}
ble_msg.act = ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT;

View File

@ -64,7 +64,7 @@ static void btc_init_bluetooth(void)
bte_main_boot_entry(btc_init_callback);
#if (SMP_INCLUDED)
btc_config_init();
//load the ble local key whitch has been store in the flash
//load the ble local key which has been stored in the flash
btc_dm_load_ble_local_keys();
#endif /* #if (SMP_INCLUDED) */
}

View File

@ -32,6 +32,7 @@
#define BTC_BLE_STORAGE_LE_KEY_LENC_STR "LE_KEY_LENC"
#define BTC_BLE_STORAGE_LE_KEY_LID_STR "LE_KEY_LID"
#define BTC_BLE_STORAGE_LE_KEY_LCSRK_STR "LE_KEY_LCSRK"
#define BTC_BLE_STORAGE_LE_AUTH_MODE_STR "AuthMode"
#define BTC_BLE_STORAGE_LOCAL_ADAPTER_STR "Adapter"
#define BTC_BLE_STORAGE_LE_LOCAL_KEY_IR_STR "LE_LOCAL_KEY_IR"
@ -66,6 +67,12 @@ bt_status_t btc_storage_remove_ble_local_keys(void);
bt_status_t btc_storage_get_ble_local_key(uint8_t key_type, char *key_value, int key_len);
bt_status_t btc_storage_set_ble_dev_auth_mode(bt_bdaddr_t *remote_bd_addr, uint8_t auth_mode, bool flush);
bt_status_t btc_storage_get_ble_dev_auth_mode(bt_bdaddr_t *remote_bd_addr, int* auth_mode);
bt_status_t btc_storage_remove_ble_dev_auth_mode(bt_bdaddr_t *remote_bd_addr, bool flush);
bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr, int *addr_type);
bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr, uint8_t addr_type, bool flush);

View File

@ -143,9 +143,21 @@ static inline void btc_a2d_data_cb_to_app(const uint8_t *data, uint32_t len)
}
}
OI_CODEC_SBC_DECODER_CONTEXT context;
OI_UINT32 contextData[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
OI_INT16 pcmData[15 * SBC_MAX_SAMPLES_PER_FRAME * SBC_MAX_CHANNELS];
#define BTC_SBC_DEC_CONTEXT_DATA_LEN (CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS))
#define BTC_SBC_DEC_PCM_DATA_LEN (15 * SBC_MAX_SAMPLES_PER_FRAME * SBC_MAX_CHANNELS)
#if BTC_SBC_DEC_DYNAMIC_MEMORY == FALSE
static OI_CODEC_SBC_DECODER_CONTEXT btc_sbc_decoder_context;
static OI_UINT32 btc_sbc_decoder_context_data[BTC_SBC_DEC_CONTEXT_DATA_LEN];
static OI_INT16 btc_sbc_pcm_data[BTC_SBC_DEC_PCM_DATA_LEN];
#else
static OI_CODEC_SBC_DECODER_CONTEXT *btc_sbc_decoder_context_ptr;
static OI_UINT32 *btc_sbc_decoder_context_data;
static OI_INT16 *btc_sbc_pcm_data;
#define btc_sbc_decoder_context (*btc_sbc_decoder_context_ptr)
#endif /* BTC_SBC_DEC_DYNAMIC_MEMORY == FALSE */
/*****************************************************************************
** Misc helper functions
@ -235,6 +247,16 @@ bool btc_a2dp_sink_startup(void)
APPL_TRACE_EVENT("## A2DP SINK START MEDIA THREAD ##");
#if (BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE)
btc_sbc_decoder_context_ptr = osi_calloc(sizeof(OI_CODEC_SBC_DECODER_CONTEXT));
btc_sbc_decoder_context_data = osi_calloc(BTC_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32));
btc_sbc_pcm_data = osi_calloc(BTC_SBC_DEC_PCM_DATA_LEN * sizeof(OI_INT16));
if (!btc_sbc_decoder_context_ptr || !btc_sbc_decoder_context_data || !btc_sbc_pcm_data) {
APPL_TRACE_ERROR("failed to allocate SBC decoder");
goto error_exit;
}
#endif /* BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE */
btc_aa_snk_queue_set = xQueueCreateSet(BTC_A2DP_SINK_TASK_QUEUE_SET_LEN);
configASSERT(btc_aa_snk_queue_set);
btc_aa_snk_data_queue = xQueueCreate(BTC_A2DP_SINK_DATA_QUEUE_LEN, sizeof(int32_t));
@ -280,6 +302,21 @@ error_exit:;
vQueueDelete(btc_aa_snk_queue_set);
btc_aa_snk_queue_set = NULL;
}
#if (BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE)
if (btc_sbc_decoder_context_ptr) {
osi_free(btc_sbc_decoder_context_ptr);
btc_sbc_decoder_context_ptr = NULL;
}
if (btc_sbc_decoder_context_data) {
osi_free(btc_sbc_decoder_context_data);
btc_sbc_decoder_context_data = NULL;
}
if (btc_sbc_pcm_data) {
osi_free(btc_sbc_pcm_data);
btc_sbc_pcm_data = NULL;
}
#endif /* BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE */
return false;
}
@ -306,6 +343,17 @@ void btc_a2dp_sink_shutdown(void)
vQueueDelete(btc_aa_snk_queue_set);
btc_aa_snk_queue_set = NULL;
#if (BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE)
osi_free(btc_sbc_decoder_context_ptr);
btc_sbc_decoder_context_ptr = NULL;
osi_free(btc_sbc_decoder_context_data);
btc_sbc_decoder_context_data = NULL;
osi_free(btc_sbc_pcm_data);
btc_sbc_pcm_data = NULL;
#endif /* BTC_SBC_DEC_DYNAMIC_MEMORY == TRUE */
}
/*****************************************************************************
@ -467,7 +515,8 @@ static void btc_a2dp_sink_handle_decoder_reset(tBTC_MEDIA_SINK_CFG_UPDATE *p_msg
btc_aa_snk_cb.rx_flush = FALSE;
APPL_TRACE_EVENT("Reset to sink role");
status = OI_CODEC_SBC_DecoderReset(&context, contextData, sizeof(contextData), 2, 2, FALSE);
status = OI_CODEC_SBC_DecoderReset(&btc_sbc_decoder_context, btc_sbc_decoder_context_data,
BTC_SBC_DEC_CONTEXT_DATA_LEN * sizeof(OI_UINT32), 2, 2, FALSE);
if (!OI_SUCCESS(status)) {
APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
}
@ -582,11 +631,11 @@ static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg)
UINT8 *sbc_start_frame = ((UINT8 *)(p_msg + 1) + p_msg->offset + 1);
int count;
UINT32 pcmBytes, availPcmBytes;
OI_INT16 *pcmDataPointer = pcmData; /*Will be overwritten on next packet receipt*/
OI_INT16 *pcmDataPointer = btc_sbc_pcm_data; /*Will be overwritten on next packet receipt*/
OI_STATUS status;
int num_sbc_frames = p_msg->num_frames_to_be_processed;
UINT32 sbc_frame_len = p_msg->len - 1;
availPcmBytes = sizeof(pcmData);
availPcmBytes = BTC_SBC_DEC_PCM_DATA_LEN * sizeof(OI_INT16);
/* XXX: Check if the below check is correct, we are checking for peer to be sink when we are sink */
if (btc_av_get_peer_sep() == AVDT_TSEP_SNK || (btc_aa_snk_cb.rx_flush)) {
@ -603,7 +652,7 @@ static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg)
for (count = 0; count < num_sbc_frames && sbc_frame_len != 0; count ++) {
pcmBytes = availPcmBytes;
status = OI_CODEC_SBC_DecodeFrame(&context, (const OI_BYTE **)&sbc_start_frame,
status = OI_CODEC_SBC_DecodeFrame(&btc_sbc_decoder_context, (const OI_BYTE **)&sbc_start_frame,
(OI_UINT32 *)&sbc_frame_len,
(OI_INT16 *)pcmDataPointer,
(OI_UINT32 *)&pcmBytes);
@ -617,7 +666,7 @@ static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg)
p_msg->len = sbc_frame_len + 1;
}
btc_a2d_data_cb_to_app((uint8_t *)pcmData, (sizeof(pcmData) - availPcmBytes));
btc_a2d_data_cb_to_app((uint8_t *)btc_sbc_pcm_data, (BTC_SBC_DEC_PCM_DATA_LEN * sizeof(OI_INT16) - availPcmBytes));
}
/*******************************************************************************

View File

@ -156,7 +156,6 @@ typedef struct {
tBTC_AV_FEEDING_MODE feeding_mode;
tBTC_AV_MEDIA_FEEDINGS_STATE media_feeding_state;
tBTC_AV_MEDIA_FEEDINGS media_feeding;
SBC_ENC_PARAMS encoder;
osi_alarm_t *media_alarm;
} tBTC_A2DP_SOURCE_CB;
@ -187,6 +186,13 @@ static QueueSetHandle_t btc_aa_src_queue_set;
static esp_a2d_source_data_cb_t btc_aa_src_data_cb = NULL;
static UINT64 last_frame_us = 0;
#if BTC_SBC_ENC_DYNAMIC_MEMORY == FALSE
static SBC_ENC_PARAMS btc_sbc_encoder;
#else
static SBC_ENC_PARAMS *btc_sbc_encoder_ptr;
#define btc_sbc_encoder (*btc_sbc_encoder_ptr)
#endif /* BTC_SBC_ENC_DYNAMIC_MEMORY == FALSE */
void btc_a2dp_src_reg_data_cb(esp_a2d_source_data_cb_t callback)
{
// todo: critical section protection
@ -310,6 +316,14 @@ bool btc_a2dp_source_startup(void)
APPL_TRACE_EVENT("## A2DP SOURCE START MEDIA THREAD ##");
#if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE
btc_sbc_encoder_ptr = osi_calloc(sizeof(SBC_ENC_PARAMS));
if (!btc_sbc_encoder_ptr) {
APPL_TRACE_ERROR("failed to allocate SBC encoder");
goto error_exit;
}
#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
btc_aa_src_queue_set = xQueueCreateSet(BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN);
configASSERT(btc_aa_src_queue_set);
btc_aa_src_data_queue = xQueueCreate(BTC_A2DP_SOURCE_DATA_QUEUE_LEN, sizeof(void *));
@ -355,6 +369,12 @@ error_exit:;
vQueueDelete(btc_aa_src_queue_set);
btc_aa_src_queue_set = NULL;
}
#if (BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE)
if (btc_sbc_encoder_ptr) {
osi_free(btc_sbc_encoder_ptr);
btc_sbc_encoder_ptr = NULL;
}
#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
return false;
}
@ -381,6 +401,11 @@ void btc_a2dp_source_shutdown(void)
vQueueDelete(btc_aa_src_queue_set);
btc_aa_src_queue_set = NULL;
#if (BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE)
osi_free(btc_sbc_encoder_ptr);
btc_sbc_encoder_ptr = NULL;
#endif /* #if BTC_SBC_ENC_DYNAMIC_MEMORY == TRUE */
}
/*****************************************************************************
@ -794,13 +819,14 @@ static void btc_a2dp_source_enc_init(BT_HDR *p_msg)
btc_aa_src_cb.timestamp = 0;
/* SBC encoder config (enforced even if not used) */
btc_aa_src_cb.encoder.s16ChannelMode = pInitAudio->ChannelMode;
btc_aa_src_cb.encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands;
btc_aa_src_cb.encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks;
btc_aa_src_cb.encoder.s16AllocationMethod = pInitAudio->AllocationMethod;
btc_aa_src_cb.encoder.s16SamplingFreq = pInitAudio->SamplingFreq;
btc_aa_src_cb.encoder.u16BitRate = btc_a2dp_source_get_sbc_rate();
btc_sbc_encoder.s16ChannelMode = pInitAudio->ChannelMode;
btc_sbc_encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands;
btc_sbc_encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks;
btc_sbc_encoder.s16AllocationMethod = pInitAudio->AllocationMethod;
btc_sbc_encoder.s16SamplingFreq = pInitAudio->SamplingFreq;
btc_sbc_encoder.u16BitRate = btc_a2dp_source_get_sbc_rate();
/* Default transcoding is PCM to SBC, modified by feeding configuration */
btc_aa_src_cb.TxTranscoding = BTC_MEDIA_TRSCD_PCM_2_SBC;
@ -811,14 +837,14 @@ static void btc_a2dp_source_enc_init(BT_HDR *p_msg)
APPL_TRACE_EVENT("btc_a2dp_source_enc_init mtu %d, peer mtu %d",
btc_aa_src_cb.TxAaMtuSize, pInitAudio->MtuSize);
APPL_TRACE_EVENT(" ch mode %d, subnd %d, nb blk %d, alloc %d, rate %d, freq %d",
btc_aa_src_cb.encoder.s16ChannelMode, btc_aa_src_cb.encoder.s16NumOfSubBands,
btc_aa_src_cb.encoder.s16NumOfBlocks,
btc_aa_src_cb.encoder.s16AllocationMethod, btc_aa_src_cb.encoder.u16BitRate,
btc_aa_src_cb.encoder.s16SamplingFreq);
btc_sbc_encoder.s16ChannelMode, btc_sbc_encoder.s16NumOfSubBands,
btc_sbc_encoder.s16NumOfBlocks,
btc_sbc_encoder.s16AllocationMethod, btc_sbc_encoder.u16BitRate,
btc_sbc_encoder.s16SamplingFreq);
/* Reset entirely the SBC encoder */
SBC_Encoder_Init(&(btc_aa_src_cb.encoder));
APPL_TRACE_DEBUG("btc_a2dp_source_enc_init bit pool %d", btc_aa_src_cb.encoder.s16BitPool);
SBC_Encoder_Init(&(btc_sbc_encoder));
APPL_TRACE_DEBUG("btc_a2dp_source_enc_init bit pool %d", btc_sbc_encoder.s16BitPool);
}
@ -835,7 +861,7 @@ static void btc_a2dp_source_enc_init(BT_HDR *p_msg)
static void btc_a2dp_source_enc_update(BT_HDR *p_msg)
{
tBTC_MEDIA_UPDATE_AUDIO *pUpdateAudio = (tBTC_MEDIA_UPDATE_AUDIO *) p_msg;
SBC_ENC_PARAMS *pstrEncParams = &btc_aa_src_cb.encoder;
SBC_ENC_PARAMS *pstrEncParams = &btc_sbc_encoder;
UINT16 s16SamplingFreq;
SINT16 s16BitPool = 0;
SINT16 s16BitRate;
@ -928,19 +954,19 @@ static void btc_a2dp_source_enc_update(BT_HDR *p_msg)
if (s16BitPool > pUpdateAudio->MaxBitPool) {
APPL_TRACE_DEBUG("%s computed bitpool too large (%d)", __FUNCTION__, s16BitPool);
/* Decrease bitrate */
btc_aa_src_cb.encoder.u16BitRate -= BTC_MEDIA_BITRATE_STEP;
btc_sbc_encoder.u16BitRate -= BTC_MEDIA_BITRATE_STEP;
/* Record that we have decreased the bitrate */
protect |= 1;
} else if (s16BitPool < pUpdateAudio->MinBitPool) {
APPL_TRACE_WARNING("%s computed bitpool too small (%d)", __FUNCTION__, s16BitPool);
/* Increase bitrate */
UINT16 previous_u16BitRate = btc_aa_src_cb.encoder.u16BitRate;
btc_aa_src_cb.encoder.u16BitRate += BTC_MEDIA_BITRATE_STEP;
UINT16 previous_u16BitRate = btc_sbc_encoder.u16BitRate;
btc_sbc_encoder.u16BitRate += BTC_MEDIA_BITRATE_STEP;
/* Record that we have increased the bitrate */
protect |= 2;
/* Check over-flow */
if (btc_aa_src_cb.encoder.u16BitRate < previous_u16BitRate) {
if (btc_sbc_encoder.u16BitRate < previous_u16BitRate) {
protect |= 3;
}
} else {
@ -957,10 +983,10 @@ static void btc_a2dp_source_enc_update(BT_HDR *p_msg)
pstrEncParams->s16BitPool = s16BitPool;
APPL_TRACE_DEBUG("%s final bit rate %d, final bit pool %d", __FUNCTION__,
btc_aa_src_cb.encoder.u16BitRate, btc_aa_src_cb.encoder.s16BitPool);
btc_sbc_encoder.u16BitRate, btc_sbc_encoder.s16BitPool);
/* make sure we reinitialize encoder with new settings */
SBC_Encoder_Init(&(btc_aa_src_cb.encoder));
SBC_Encoder_Init(&(btc_sbc_encoder));
}
}
@ -991,10 +1017,10 @@ static void btc_a2dp_source_pcm2sbc_init(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_feedin
case 32000:
case 48000:
/* For these sampling_freq the AV connection must be 48000 */
if (btc_aa_src_cb.encoder.s16SamplingFreq != SBC_sf48000) {
if (btc_sbc_encoder.s16SamplingFreq != SBC_sf48000) {
/* Reconfiguration needed at 48000 */
APPL_TRACE_DEBUG("SBC Reconfiguration needed at 48000");
btc_aa_src_cb.encoder.s16SamplingFreq = SBC_sf48000;
btc_sbc_encoder.s16SamplingFreq = SBC_sf48000;
reconfig_needed = TRUE;
}
break;
@ -1003,10 +1029,10 @@ static void btc_a2dp_source_pcm2sbc_init(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_feedin
case 22050:
case 44100:
/* For these sampling_freq the AV connection must be 44100 */
if (btc_aa_src_cb.encoder.s16SamplingFreq != SBC_sf44100) {
if (btc_sbc_encoder.s16SamplingFreq != SBC_sf44100) {
/* Reconfiguration needed at 44100 */
APPL_TRACE_DEBUG("SBC Reconfiguration needed at 44100");
btc_aa_src_cb.encoder.s16SamplingFreq = SBC_sf44100;
btc_sbc_encoder.s16SamplingFreq = SBC_sf44100;
reconfig_needed = TRUE;
}
break;
@ -1016,21 +1042,21 @@ static void btc_a2dp_source_pcm2sbc_init(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_feedin
}
/* Some AV Headsets do not support Mono => always ask for Stereo */
if (btc_aa_src_cb.encoder.s16ChannelMode == SBC_MONO) {
if (btc_sbc_encoder.s16ChannelMode == SBC_MONO) {
APPL_TRACE_DEBUG("SBC Reconfiguration needed in Stereo");
btc_aa_src_cb.encoder.s16ChannelMode = SBC_JOINT_STEREO;
btc_sbc_encoder.s16ChannelMode = SBC_JOINT_STEREO;
reconfig_needed = TRUE;
}
if (reconfig_needed != FALSE) {
APPL_TRACE_DEBUG("%s :: mtu %d", __FUNCTION__, btc_aa_src_cb.TxAaMtuSize);
APPL_TRACE_DEBUG("ch mode %d, nbsubd %d, nb %d, alloc %d, rate %d, freq %d",
btc_aa_src_cb.encoder.s16ChannelMode,
btc_aa_src_cb.encoder.s16NumOfSubBands, btc_aa_src_cb.encoder.s16NumOfBlocks,
btc_aa_src_cb.encoder.s16AllocationMethod, btc_aa_src_cb.encoder.u16BitRate,
btc_aa_src_cb.encoder.s16SamplingFreq);
btc_sbc_encoder.s16ChannelMode,
btc_sbc_encoder.s16NumOfSubBands, btc_sbc_encoder.s16NumOfBlocks,
btc_sbc_encoder.s16AllocationMethod, btc_sbc_encoder.u16BitRate,
btc_sbc_encoder.s16SamplingFreq);
SBC_Encoder_Init(&(btc_aa_src_cb.encoder));
SBC_Encoder_Init(&(btc_sbc_encoder));
} else {
APPL_TRACE_DEBUG("%s no SBC reconfig needed", __FUNCTION__);
}
@ -1105,8 +1131,8 @@ static UINT8 btc_get_num_aa_frame(void)
switch (btc_aa_src_cb.TxTranscoding) {
case BTC_MEDIA_TRSCD_PCM_2_SBC: {
UINT32 pcm_bytes_per_frame = btc_aa_src_cb.encoder.s16NumOfSubBands *
btc_aa_src_cb.encoder.s16NumOfBlocks *
UINT32 pcm_bytes_per_frame = btc_sbc_encoder.s16NumOfSubBands *
btc_sbc_encoder.s16NumOfBlocks *
btc_aa_src_cb.media_feeding.cfg.pcm.num_channel *
btc_aa_src_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
@ -1162,12 +1188,12 @@ static UINT8 btc_get_num_aa_frame(void)
BOOLEAN btc_media_aa_read_feeding(void)
{
UINT16 blocm_x_subband = btc_aa_src_cb.encoder.s16NumOfSubBands * \
btc_aa_src_cb.encoder.s16NumOfBlocks;
UINT16 blocm_x_subband = btc_sbc_encoder.s16NumOfSubBands * \
btc_sbc_encoder.s16NumOfBlocks;
UINT32 read_size;
UINT16 sbc_sampling = 48000;
UINT32 src_samples;
UINT16 bytes_needed = blocm_x_subband * btc_aa_src_cb.encoder.s16NumOfChannels * \
UINT16 bytes_needed = blocm_x_subband * btc_sbc_encoder.s16NumOfChannels * \
btc_aa_src_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
static UINT16 up_sampled_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
* SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * 2];
@ -1181,7 +1207,7 @@ BOOLEAN btc_media_aa_read_feeding(void)
UINT32 nb_byte_read = 0;
/* Get the SBC sampling rate */
switch (btc_aa_src_cb.encoder.s16SamplingFreq) {
switch (btc_sbc_encoder.s16SamplingFreq) {
case SBC_sf48000:
sbc_sampling = 48000;
break;
@ -1199,7 +1225,7 @@ BOOLEAN btc_media_aa_read_feeding(void)
if (sbc_sampling == btc_aa_src_cb.media_feeding.cfg.pcm.sampling_freq) {
read_size = bytes_needed - btc_aa_src_cb.media_feeding_state.pcm.aa_feed_residue;
nb_byte_read = btc_aa_src_data_read(
((uint8_t *)btc_aa_src_cb.encoder.as16PcmBuffer) +
((uint8_t *)btc_sbc_encoder.as16PcmBuffer) +
btc_aa_src_cb.media_feeding_state.pcm.aa_feed_residue,
read_size);
if (nb_byte_read == read_size) {
@ -1293,7 +1319,7 @@ BOOLEAN btc_media_aa_read_feeding(void)
/* only copy the pcm sample when we have up-sampled enough PCM */
if (btc_aa_src_cb.media_feeding_state.pcm.aa_feed_residue >= bytes_needed) {
/* Copy the output pcm samples in SBC encoding buffer */
memcpy((UINT8 *)btc_aa_src_cb.encoder.as16PcmBuffer,
memcpy((UINT8 *)btc_sbc_encoder.as16PcmBuffer,
(UINT8 *)up_sampled_buffer,
bytes_needed);
/* update the residue */
@ -1322,8 +1348,8 @@ BOOLEAN btc_media_aa_read_feeding(void)
static void btc_media_aa_prep_sbc_2_send(UINT8 nb_frame)
{
BT_HDR *p_buf;
UINT16 blocm_x_subband = btc_aa_src_cb.encoder.s16NumOfSubBands *
btc_aa_src_cb.encoder.s16NumOfBlocks;
UINT16 blocm_x_subband = btc_sbc_encoder.s16NumOfSubBands *
btc_sbc_encoder.s16NumOfBlocks;
while (nb_frame) {
if (NULL == (p_buf = osi_malloc(BTC_MEDIA_AA_BUF_SIZE))) {
@ -1339,27 +1365,27 @@ static void btc_media_aa_prep_sbc_2_send(UINT8 nb_frame)
do {
/* Write @ of allocated buffer in encoder.pu8Packet */
btc_aa_src_cb.encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len;
btc_sbc_encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len;
/* Fill allocated buffer with 0 */
memset(btc_aa_src_cb.encoder.as16PcmBuffer, 0, blocm_x_subband
* btc_aa_src_cb.encoder.s16NumOfChannels);
memset(btc_sbc_encoder.as16PcmBuffer, 0, blocm_x_subband
* btc_sbc_encoder.s16NumOfChannels);
/* Read PCM data and upsample them if needed */
if (btc_media_aa_read_feeding()) {
/* SBC encode and descramble frame */
SBC_Encoder(&(btc_aa_src_cb.encoder));
A2D_SbcChkFrInit(btc_aa_src_cb.encoder.pu8Packet);
A2D_SbcDescramble(btc_aa_src_cb.encoder.pu8Packet, btc_aa_src_cb.encoder.u16PacketLength);
SBC_Encoder(&(btc_sbc_encoder));
A2D_SbcChkFrInit(btc_sbc_encoder.pu8Packet);
A2D_SbcDescramble(btc_sbc_encoder.pu8Packet, btc_sbc_encoder.u16PacketLength);
/* Update SBC frame length */
p_buf->len += btc_aa_src_cb.encoder.u16PacketLength;
p_buf->len += btc_sbc_encoder.u16PacketLength;
nb_frame--;
p_buf->layer_specific++;
} else {
APPL_TRACE_WARNING("btc_media_aa_prep_sbc_2_send underflow %d, %d",
nb_frame, btc_aa_src_cb.media_feeding_state.pcm.aa_feed_residue);
btc_aa_src_cb.media_feeding_state.pcm.counter += nb_frame *
btc_aa_src_cb.encoder.s16NumOfSubBands *
btc_aa_src_cb.encoder.s16NumOfBlocks *
btc_sbc_encoder.s16NumOfSubBands *
btc_sbc_encoder.s16NumOfBlocks *
btc_aa_src_cb.media_feeding.cfg.pcm.num_channel *
btc_aa_src_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
/* no more pcm to read */
@ -1372,7 +1398,7 @@ static void btc_media_aa_prep_sbc_2_send(UINT8 nb_frame)
}
}
} while (((p_buf->len + btc_aa_src_cb.encoder.u16PacketLength) < btc_aa_src_cb.TxAaMtuSize)
} while (((p_buf->len + btc_sbc_encoder.u16PacketLength) < btc_aa_src_cb.TxAaMtuSize)
&& (p_buf->layer_specific < 0x0F) && nb_frame);
if (p_buf->len) {

View File

@ -426,6 +426,35 @@ static void btc_stop_adv_callback(uint8_t status)
}
}
void btc_update_duplicate_exceptional_list_callback(tBTA_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_COMPLETE_EVT;
param.update_duplicate_exceptional_list_cmpl.status = status;
param.update_duplicate_exceptional_list_cmpl.subcode = subcode;
if(length > sizeof(param.update_duplicate_exceptional_list_cmpl.device_info)) {
length = sizeof(param.update_duplicate_exceptional_list_cmpl.device_info);
}
param.update_duplicate_exceptional_list_cmpl.length = length;
memcpy(param.update_duplicate_exceptional_list_cmpl.device_info, device_info, length);
ret = btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_ble_update_duplicate_exceptional_list(uint8_t subcode, uint32_t info_type, BD_ADDR device_info,
tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK p_update_duplicate_ignore_list_cback)
{
BTA_DmUpdateDuplicateExceptionalList(subcode, info_type, device_info, p_update_duplicate_ignore_list_cback);
}
static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params, tBTA_START_ADV_CMPL_CBACK start_adv_cback)
{
tBLE_BD_ADDR peer_addr;
@ -452,6 +481,10 @@ static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params, tBT
status = ESP_BT_STATUS_PARM_INVALID;
BTC_TRACE_ERROR("Invalid advertisting channel map parameters.\n");
}
if (!BLE_ISVALID_PARAM(ble_adv_params->peer_addr_type, BLE_ADDR_TYPE_PUBLIC, BLE_ADDR_TYPE_RANDOM)) {
status = ESP_BT_STATUS_PARM_INVALID;
BTC_TRACE_ERROR("Invalid advertisting peer address type parameters.\n");
}
if(status != ESP_BT_STATUS_SUCCESS) {
if(start_adv_cback) {
start_adv_cback(status);
@ -571,6 +604,9 @@ static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data
case BTA_DM_SEARCH_CANCEL_CMPL_EVT:
BTC_TRACE_DEBUG("BTA_DM_SEARCH_CANCEL_CMPL_EVT\n");
break;
case BTA_DM_INQ_DISCARD_NUM_EVT:
param.scan_rst.num_dis = p_data->inq_dis.num_dis;
break;
default:
BTC_TRACE_ERROR("%s : Unknown event 0x%x\n", __FUNCTION__, event);
return;
@ -831,7 +867,7 @@ static void btc_ble_set_rand_addr (BD_ADDR rand_addr, tBTA_SET_RAND_ADDR_CBACK *
BTA_DmSetRandAddress(rand_addr, btc_set_rand_addr_callback);
} else {
btc_set_rand_addr_callback(BTM_INVALID_STATIC_RAND_ADDR);
BTC_TRACE_ERROR("Invalid random address, the high bit should be 0b11, all bits of the random part shall not be to 1 or 0");
BTC_TRACE_ERROR("Invalid random address, the high bit should be 0b11, bits of the random part shall not be all 1 or 0");
}
} else {
btc_set_rand_addr_callback(BTM_INVALID_STATIC_RAND_ADDR);
@ -1082,6 +1118,12 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
arg->cfg_scan_rsp_data_raw.raw_scan_rsp_len,
btc_scan_rsp_data_raw_callback);
break;
case BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST:
btc_ble_update_duplicate_exceptional_list(arg->update_duplicate_exceptional_list.subcode,
arg->update_duplicate_exceptional_list.info_type,
arg->update_duplicate_exceptional_list.device_info,
btc_update_duplicate_exceptional_list_callback);
break;
#if (SMP_INCLUDED == TRUE)
case BTC_GAP_BLE_SET_ENCRYPTION_EVT: {
BD_ADDR bd_addr;

View File

@ -750,7 +750,7 @@ void btc_gap_bt_arg_deep_free(btc_msg_t *msg)
break;
#endif ///BT_SSP_INCLUDED == TRUE
default:
BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
BTC_TRACE_ERROR("Unhandled deep copy %d, arg: %p\n", msg->act, arg);
break;
}
}

View File

@ -46,6 +46,7 @@ typedef enum {
BTC_GAP_BLE_CONFIRM_REPLY_EVT,
BTC_GAP_BLE_DISCONNECT_EVT,
BTC_GAP_BLE_REMOVE_BOND_DEV_EVT,
BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST,
} btc_gap_ble_act_t;
/* btc_ble_gap_args_t */
@ -94,6 +95,12 @@ typedef union {
bool add_remove;
esp_bd_addr_t remote_bda;
}update_white_list;
//BTC_GAP_BLE_UPDATE_DUPLICATE_SCAN_EXCEPTIONAL_LIST
struct update_duplicate_exceptional_list_args {
uint8_t subcode;
uint32_t info_type;
esp_duplicate_info_t device_info;
}update_duplicate_exceptional_list;
//BTC_GAP_BLE_ACT_SET_CONN_PARAMS
struct set_conn_params_args {
esp_bd_addr_t bd_addr;

View File

@ -130,6 +130,24 @@
#define BLE_PRIVACY_SPT FALSE
#endif /* CONFIG_SMP_ENABLE */
#ifndef CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED
#define BLE_ADV_REPORT_FLOW_CONTROL FALSE
#else
#define BLE_ADV_REPORT_FLOW_CONTROL CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED
#endif /* CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED */
#ifndef CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM
#define BLE_ADV_REPORT_FLOW_CONTROL_NUM 100
#else
#define BLE_ADV_REPORT_FLOW_CONTROL_NUM CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM
#endif /* CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM */
#ifndef CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD
#define BLE_ADV_REPORT_DISCARD_THRSHOLD 20
#else
#define BLE_ADV_REPORT_DISCARD_THRSHOLD CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD
#endif /* CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD */
#if (CONFIG_BT_ACL_CONNECTIONS)
#define MAX_ACL_CONNECTIONS CONFIG_BT_ACL_CONNECTIONS
#define GATT_MAX_PHY_CHANNEL CONFIG_BT_ACL_CONNECTIONS
@ -324,6 +342,12 @@
#define GATTS_SEND_SERVICE_CHANGE_MODE CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE
#endif
#ifndef CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY
#define BTM_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY FALSE
#else
#define BTM_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY
#endif
/* This feature is used to eanble interleaved scan*/
#ifndef BTA_HOST_INTERLEAVE_SEARCH
#define BTA_HOST_INTERLEAVE_SEARCH FALSE//FALSE

View File

@ -100,7 +100,11 @@ static void start_up(void)
response = AWAIT_COMMAND(packet_factory->make_set_c2h_flow_control(HCI_HOST_FLOW_CTRL_ACL_ON));
packet_parser->parse_generic_command_complete(response);
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
// Enable adv flow control
response = AWAIT_COMMAND(packet_factory->make_set_adv_report_flow_control(HCI_HOST_FLOW_CTRL_ADV_REPORT_ON, (uint16_t)BLE_ADV_REPORT_FLOW_CONTROL_NUM, (uint16_t)BLE_ADV_REPORT_DISCARD_THRSHOLD));
packet_parser->parse_generic_command_complete(response);
#endif
// Tell the controller about our buffer sizes and buffer counts next
// TODO(zachoverflow): factor this out. eww l2cap contamination. And why just a hardcoded 10?
response = AWAIT_COMMAND(
@ -250,10 +254,10 @@ static void start_up(void)
}
#endif
if (simple_pairing_supported) {
response = AWAIT_COMMAND(packet_factory->make_set_event_mask(&CLASSIC_EVENT_MASK));
packet_parser->parse_generic_command_complete(response);
}
response = AWAIT_COMMAND(packet_factory->make_set_event_mask(&CLASSIC_EVENT_MASK));
packet_parser->parse_generic_command_complete(response);
#if (BTM_SCO_HCI_INCLUDED == TRUE)
response = AWAIT_COMMAND(packet_factory->make_write_sync_flow_control_enable(1));

View File

@ -55,6 +55,7 @@ static const uint16_t outbound_event_types[] = {
typedef struct {
size_t buffer_size;
fixed_queue_t *rx_q;
uint16_t adv_free_num;
} hci_hal_env_t;
@ -81,6 +82,7 @@ static void hci_hal_env_init(
assert(max_buffer_count > 0);
hci_hal_env.buffer_size = buffer_size;
hci_hal_env.adv_free_num = 0;
hci_hal_env.rx_q = fixed_queue_new(max_buffer_count);
if (hci_hal_env.rx_q) {
@ -102,8 +104,11 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks)
{
assert(upper_callbacks != NULL);
callbacks = upper_callbacks;
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, BLE_ADV_REPORT_FLOW_CONTROL_NUM + L2CAP_HOST_FC_ACL_BUFS + QUEUE_SIZE_MAX); // adv flow control num + ACL flow control num + hci cmd numeber
#else
hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, QUEUE_SIZE_MAX);
#endif
xHciH4Queue = xQueueCreate(HCI_H4_QUEUE_LEN, sizeof(BtTaskEvt_t));
xTaskCreatePinnedToCore(hci_hal_h4_rx_handler, HCI_H4_TASK_NAME, HCI_H4_TASK_STACK_SIZE, NULL, HCI_H4_TASK_PRIO, &xHciH4TaskHandle, HCI_H4_TASK_PINNED_TO_CORE);
@ -223,12 +228,37 @@ static void hci_packet_complete(BT_HDR *packet){
bool host_recv_adv_packet(BT_HDR *packet)
{
assert(packet);
if(packet->data[0] == DATA_TYPE_EVENT && packet->data[1] == HCI_BLE_EVENT && packet->data[3] == HCI_BLE_ADV_PKT_RPT_EVT) {
return true;
if(packet->data[0] == DATA_TYPE_EVENT && packet->data[1] == HCI_BLE_EVENT) {
if(packet->data[3] == HCI_BLE_ADV_PKT_RPT_EVT
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|| packet->data[3] == HCI_BLE_ADV_DISCARD_REPORT_EVT
#endif
) {
return true;
}
}
return false;
}
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
static void hci_update_adv_report_flow_control(BT_HDR *packet)
{
// this is adv packet
if(host_recv_adv_packet(packet)) {
// update adv free number
hci_hal_env.adv_free_num ++;
if (esp_vhci_host_check_send_available()){
// send hci cmd
btsnd_hcic_ble_update_adv_report_flow_control(hci_hal_env.adv_free_num);
hci_hal_env.adv_free_num = 0;
} else {
//do nothing
}
}
}
#endif
static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
{
uint8_t type, hdr_size;
@ -282,6 +312,11 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
osi_free(packet);
return;
}
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_update_adv_report_flow_control(packet);
#endif
#if SCAN_QUEUE_CONGEST_CHECK
if(BTU_check_queue_is_congest() && host_recv_adv_packet(packet)) {
HCI_TRACE_ERROR("BtuQueue is congested");
@ -289,7 +324,6 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
return;
}
#endif
packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
callbacks->packet_ready(packet);
}

View File

@ -317,7 +317,11 @@ static void event_command_ready(fixed_queue_t *queue)
wait_entry = fixed_queue_dequeue(queue);
if(wait_entry->opcode == HCI_HOST_NUM_PACKETS_DONE){
if(wait_entry->opcode == HCI_HOST_NUM_PACKETS_DONE
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|| wait_entry->opcode == HCI_VENDOR_BLE_ADV_REPORT_FLOW_CONTROL
#endif
){
packet_fragmenter->fragment_and_dispatch(wait_entry->command);
osi_free(wait_entry->command);
osi_free(wait_entry);

View File

@ -53,6 +53,18 @@ static BT_HDR *make_set_c2h_flow_control(uint8_t enable)
return packet;
}
static BT_HDR *make_set_adv_report_flow_control(uint8_t enable, uint16_t num, uint16_t lost_threshold)
{
uint8_t *stream;
const uint8_t parameter_size = 1 + 2 + 2;
BT_HDR *packet = make_command(HCI_VENDOR_BLE_SET_ADV_FLOW_CONTROL, parameter_size, &stream);
UINT8_TO_STREAM(stream, enable);
UINT16_TO_STREAM(stream, num);
UINT16_TO_STREAM(stream, lost_threshold);
return packet;
}
static BT_HDR *make_host_buffer_size(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count)
{
uint8_t *stream;
@ -239,6 +251,7 @@ static const hci_packet_factory_t interface = {
make_reset,
make_read_buffer_size,
make_set_c2h_flow_control,
make_set_adv_report_flow_control,
make_host_buffer_size,
make_read_local_version_info,
make_read_bd_addr,

View File

@ -26,6 +26,7 @@ typedef struct {
BT_HDR *(*make_reset)(void);
BT_HDR *(*make_read_buffer_size)(void);
BT_HDR *(*make_set_c2h_flow_control)(uint8_t enable);
BT_HDR *(*make_set_adv_report_flow_control)(uint8_t enable, uint16_t num, uint16_t lost_threshold);
BT_HDR *(*make_host_buffer_size)(uint16_t acl_size, uint8_t sco_size, uint16_t acl_count, uint16_t sco_count);
BT_HDR *(*make_read_local_version_info)(void);
BT_HDR *(*make_read_bd_addr)(void);

View File

@ -43,7 +43,7 @@
//#include "osi/include/log.h"
#if SMP_INCLUDED == TRUE
// The temp variable to pass parameter between functions when in the connected event comeback.
// The temp variable to pass parameter between functions when in the connected event callback.
static BOOLEAN temp_enhanced = FALSE;
extern BOOLEAN aes_cipher_msg_auth_code(BT_OCTET16 key, UINT8 *input, UINT16 length,
UINT16 tlen, UINT8 *p_signature);
@ -66,13 +66,14 @@ extern void gatt_notify_enc_cmpl(BD_ADDR bd_addr);
** bd_name - Name of the peer device. NULL if unknown.
** dev_type - Remote device's device type.
** addr_type - LE device address type.
** auth_mode - auth mode
**
** Returns TRUE if added OK, else FALSE
**
*******************************************************************************/
#if (SMP_INCLUDED == TRUE)
BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE dev_type,
tBLE_ADDR_TYPE addr_type)
tBLE_ADDR_TYPE addr_type, UINT32 auth_mode)
{
tBTM_SEC_DEV_REC *p_dev_rec;
UINT8 i = 0;
@ -125,6 +126,7 @@ BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name, tBT_DEVICE_TYPE d
}
p_dev_rec->device_type |= dev_type;
p_dev_rec->ble.ble_addr_type = addr_type;
p_dev_rec->ble.auth_mode = auth_mode;
memcpy (p_dev_rec->ble.pseudo_addr, bd_addr, BD_ADDR_LEN);
/* sync up with the Inq Data base*/
@ -629,7 +631,7 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR
*p_addr_type = BLE_ADDR_PUBLIC;
if (!p_dev_rec) {
if (!p_dev_rec) {
*p_dev_type = BT_DEVICE_TYPE_BREDR;
/* Check with the BT manager if details about remote device are known */
if (p_inq_info != NULL) {
@ -1471,7 +1473,7 @@ tBTM_STATUS btm_ble_set_encryption (BD_ADDR bd_addr, void *p_ref_data, UINT8 lin
if(link_role == BTM_ROLE_SLAVE && (p_rec->ble.key_type & BTM_LE_KEY_PENC)) {
p_rec->ble.skip_update_conn_param = true;
} else {
p_rec->ble.skip_update_conn_param = false;
p_rec->ble.skip_update_conn_param = false;
}
if (SMP_Pair(bd_addr) == SMP_STARTED) {
cmd = BTM_CMD_STARTED;
@ -1620,7 +1622,7 @@ void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable)
/* to notify GATT to send data if any request is pending */
gatt_notify_enc_cmpl(p_dev_rec->ble.pseudo_addr);
}
#endif ///SMP_INCLUDED == TRUE
#endif ///SMP_INCLUDED == TRUE
/*******************************************************************************
@ -1946,10 +1948,10 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced)
/* It will cause that scanner doesn't send scan request to advertiser
* which has sent IRK to us and we have stored the IRK in controller.
* It is a design problem of hardware. The temporal solution is not to
* send the key to the controller and then resolve the random address in host.
* so we need send the real address information to controller to connect.
* Once the connection is successful, resolve device address whether it is
* It is a hardware limitation. The preliminary solution is not to
* send key to the controller, but to resolve the random address in host.
* so we need send the real address information to controller to connect.
* Once the connection is successful, resolve device address whether it is
* slave or master*/
/* if (!match && role == HCI_ROLE_SLAVE && BTM_BLE_IS_RESOLVE_BDA(bda)) { */

View File

@ -439,7 +439,7 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration,
**
*******************************************************************************/
tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration,
tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb)
tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb, tBTM_INQ_DIS_CB *p_discard_cb)
{
tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
tBTM_STATUS status = BTM_WRONG_MODE;
@ -457,6 +457,7 @@ tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration,
btm_cb.ble_ctr_cb.p_scan_results_cb = p_results_cb;
btm_cb.ble_ctr_cb.p_scan_cmpl_cb = p_cmpl_cb;
btm_cb.ble_ctr_cb.p_obs_discard_cb = p_discard_cb;
status = BTM_CMD_STARTED;
/* scan is not started */
@ -708,6 +709,37 @@ extern void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK *p_vsc_c
return ;
}
void BTM_VendorHciEchoCmdCallback(tBTM_VSC_CMPL *p1)
{
if (!p1) {
return;
}
uint8_t *p = p1->p_param_buf;
uint8_t status, echo;
STREAM_TO_UINT8 (status, p);
STREAM_TO_UINT8 (echo, p);
BTM_TRACE_DEBUG("%s status 0x%x echo 0x%x", __func__, status, echo);
}
/******************************************************************************
**
** Function BTM_VendorHciEchoCmdTest
**
** Description vendor common echo hci cmd test, controller will return status and echo
**
** Parameters: echo : echo value
**
** Returns void
**
*******************************************************************************/
void BTM_VendorHciEchoCmdTest(uint8_t echo)
{
BTM_VendorSpecificCommand (HCI_VENDOR_COMMON_ECHO_CMD_OPCODE,
1,
&echo,
BTM_VendorHciEchoCmdCallback);
}
/*******************************************************************************
**
** Function BTM_BleEnableMixedPrivacyMode
@ -1615,6 +1647,52 @@ tBTM_STATUS BTM_BleWriteScanRspRaw(UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_le
}
}
/*******************************************************************************
**
** Function BTM_UpdateBleDuplicateExceptionalList
**
** Description This function is called to update duplicate scan exceptional list.
**
** Parameters: subcode: add, remove or clean duplicate scan exceptional list.
** type: device info type
** device_info: device information
** update_exceptional_list_cmp_cb: complete callback
**
** Returns status
**
*******************************************************************************/
tBTM_STATUS BTM_UpdateBleDuplicateExceptionalList(uint8_t subcode, uint32_t type, BD_ADDR device_info,
tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK update_exceptional_list_cmp_cb)
{
tBTM_BLE_CB *ble_cb = &btm_cb.ble_ctr_cb;
ble_cb->update_exceptional_list_cmp_cb = update_exceptional_list_cmp_cb;
tBTM_STATUS status = BTM_NO_RESOURCES;
if (!controller_get_interface()->supports_ble()) {
return BTM_ILLEGAL_VALUE;
}
if(!device_info) {
return BTM_ILLEGAL_VALUE;
}
// subcoe + type + device info
uint8_t device_info_array[1 + 4 + BD_ADDR_LEN] = {0};
device_info_array[0] = subcode;
device_info_array[1] = type & 0xff;
device_info_array[2] = (type >> 8) & 0xff;
device_info_array[3] = (type >> 16) & 0xff;
device_info_array[4] = (type >> 24) & 0xff;
if(type == BTM_DUPLICATE_SCAN_EXCEPTIONAL_INFO_ADV_ADDR) {
bt_rcopy(&device_info_array[5], device_info, BD_ADDR_LEN);
} else {
memcpy(&device_info_array[5], device_info, 4);
}
status = BTM_VendorSpecificCommand(HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST, 1 + 4 + BD_ADDR_LEN, device_info_array, NULL);
if(status == BTM_CMD_STARTED) {
status = BTM_SUCCESS;
}
return status;
}
/*******************************************************************************
**
** Function BTM_BleWriteAdvData
@ -3019,7 +3097,9 @@ BOOLEAN btm_ble_update_inq_result(BD_ADDR bda, tINQ_DB_ENT *p_i, UINT8 addr_type
BTM_TRACE_DEBUG("btm_ble_update_inq_result scan_rsp=false, to_report=false,\
scan_type_active=%d", btm_cb.ble_ctr_cb.inq_var.scan_type);
p_i->scan_rsp = FALSE;
#if BTM_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY == FALSE
to_report = FALSE;
#endif
} else {
p_i->scan_rsp = TRUE;
}
@ -3316,9 +3396,26 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
BOOLEAN update = TRUE;
UINT8 result = 0;
//if scan duplicate is enabled, the adv packet without scan response is allowed to report to higgher layer
/* Event_Type:
0x00 Connectable undirected advertising (ADV_IND).
0x01 Connectable directed advertising (ADV_DIRECT_IND)
0x02 Scannable undirected advertising (ADV_SCAN_IND)
0x03 Non connectable undirected advertising (ADV_NONCONN_IND)
0x04 Scan Response (SCAN_RSP)
0x05-0xFF Reserved for future use
*/
//if scan duplicate is enabled, the adv packet without scan response is allowed to report to higher layer
if(p_le_inq_cb->scan_duplicate_filter == BTM_BLE_SCAN_DUPLICATE_ENABLE) {
if(memcmp(bda, p_le_inq_cb->adv_addr, BD_ADDR_LEN) != 0) {
/*
Bluedroid will put the advertising packet and scan response into a packet and send it to the higher layer.
If two advertising packets are not with the same address, or can't be combined into a packet, then the first advertising
packet will be discarded. So we added the following judgment:
1. For different addresses, send the last advertising packet to higher layer
2. For same address and same advertising type (not scan response), send the last advertising packet to higher layer
3. For same address and scan response, do nothing
*/
int same_addr = memcmp(bda, p_le_inq_cb->adv_addr, BD_ADDR_LEN);
if (same_addr != 0 || (same_addr == 0 && evt_type != BTM_BLE_SCAN_RSP_EVT)) {
btm_ble_process_last_adv_pkt();
}
}
@ -3417,6 +3514,17 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt
}
}
void btm_ble_process_adv_discard_evt(UINT8 *p)
{
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
uint32_t num_dis = 0;
STREAM_TO_UINT32 (num_dis, p);
tBTM_INQ_DIS_CB *p_obs_discard_cb = btm_cb.ble_ctr_cb.p_obs_discard_cb;
if(p_obs_discard_cb) {
(p_obs_discard_cb)(num_dis);
}
#endif
}
/*******************************************************************************
**
** Function btm_ble_start_scan

View File

@ -771,8 +771,8 @@ BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
}
/* It will cause that scanner doesn't send scan request to advertiser
* which has sent IRK to us and we have stored the IRK in controller.
* It is a design problem of hardware. The temporal solution is not to
* send the key to the controller and then resolve the random address in host. */
* It is a hardware limitation. The preliminary solution is not to
* send key to the controller, but to resolve the random address in host. */
/*
BTM_TRACE_DEBUG("%s:adding device to controller resolving list\n", __func__);
UINT8 *peer_irk = p_dev_rec->ble.keys.irk;

View File

@ -689,6 +689,21 @@ tBTM_STATUS BTM_VendorSpecificCommand(UINT16 opcode, UINT8 param_len,
void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
tBTM_CMPL_CB *p_vsc_cplt_cback)
{
tBTM_BLE_CB *ble_cb = &btm_cb.ble_ctr_cb;
switch(opcode) {
case HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST: {
uint8_t subcode, status; uint32_t length;
STREAM_TO_UINT8(status, p);
STREAM_TO_UINT8(subcode, p);
STREAM_TO_UINT32(length, p);
if(ble_cb && ble_cb->update_exceptional_list_cmp_cb) {
(*ble_cb->update_exceptional_list_cmp_cb)(status, subcode, length, p);
}
break;
}
default:
break;
}
tBTM_VSC_CMPL vcs_cplt_params;
/* If there was a callback address for vcs complete, call it */

View File

@ -5030,42 +5030,13 @@ void btm_sec_pin_code_request (UINT8 *p_bda)
memcpy (p_cb->connecting_bda, p_bda, BD_ADDR_LEN);
memcpy (p_cb->connecting_dc, p_dev_rec->dev_class, DEV_CLASS_LEN);
/* Check if the name is known */
/* Even if name is not known we might not be able to get one */
/* this is the case when we are already getting something from the */
/* device, so HCI level is flow controlled */
/* Also cannot send remote name request while paging, i.e. connection is not completed */
if (p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN) {
BTM_TRACE_EVENT ("btm_sec_pin_code_request going for callback\n");
btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
if (p_cb->api.p_pin_callback) {
(*p_cb->api.p_pin_callback) (p_bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name,
(p_dev_rec->p_cur_service == NULL) ? FALSE
: (p_dev_rec->p_cur_service->security_flags
& BTM_SEC_IN_MIN_16_DIGIT_PIN));
}
} else {
BTM_TRACE_EVENT ("btm_sec_pin_code_request going for remote name\n");
/* We received PIN code request for the device with unknown name */
/* it is not user friendly just to ask for the PIN without name */
/* try to get name at first */
if (!btsnd_hcic_rmt_name_req (p_dev_rec->bd_addr,
HCI_PAGE_SCAN_REP_MODE_R1,
HCI_MANDATARY_PAGE_SCAN_MODE, 0)) {
p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
p_dev_rec->sec_bd_name[0] = 'f';
p_dev_rec->sec_bd_name[1] = '0';
BTM_TRACE_ERROR ("can not send rmt_name_req?? fake a name and call callback\n");
btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
if (p_cb->api.p_pin_callback)
(*p_cb->api.p_pin_callback) (p_bda, p_dev_rec->dev_class,
p_dev_rec->sec_bd_name, (p_dev_rec->p_cur_service == NULL) ? FALSE
: (p_dev_rec->p_cur_service->security_flags
& BTM_SEC_IN_MIN_16_DIGIT_PIN));
}
BTM_TRACE_EVENT ("btm_sec_pin_code_request going for callback\n");
btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
if (p_cb->api.p_pin_callback) {
(*p_cb->api.p_pin_callback) (p_bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name,
(p_dev_rec->p_cur_service == NULL) ? FALSE
: (p_dev_rec->p_cur_service->security_flags
& BTM_SEC_IN_MIN_16_DIGIT_PIN));
}
}
return;

View File

@ -280,6 +280,9 @@ typedef UINT16 tBTM_BLE_STATE_MASK;
#define BTM_LE_RESOLVING_LIST_MAX 0x20
#endif
#define BTM_DUPLICATE_SCAN_EXCEPTIONAL_INFO_ADV_ADDR 0
#define BTM_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID 1
typedef struct {
BD_ADDR *resolve_q_random_pseudo;
UINT8 *resolve_q_action;
@ -317,6 +320,7 @@ typedef struct {
/* observer callback and timer */
tBTM_INQ_RESULTS_CB *p_obs_results_cb;
tBTM_CMPL_CB *p_obs_cmpl_cb;
tBTM_INQ_DIS_CB *p_obs_discard_cb;
TIMER_LIST_ENT obs_timer_ent;
/* scan callback and timer */
@ -357,6 +361,7 @@ typedef struct {
/* current BLE link state */
tBTM_BLE_STATE_MASK cur_states; /* bit mask of tBTM_BLE_STATE */
UINT8 link_count[2]; /* total link count master and slave*/
tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK *update_exceptional_list_cmp_cb;
} tBTM_BLE_CB;
#ifdef __cplusplus
@ -365,6 +370,7 @@ extern "C" {
void btm_ble_timeout(TIMER_LIST_ENT *p_tle);
void btm_ble_process_adv_pkt (UINT8 *p);
void btm_ble_process_adv_discard_evt(UINT8 *p);
void btm_ble_proc_scan_rsp_rpt (UINT8 *p);
tBTM_STATUS btm_ble_read_remote_name(BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur, tBTM_CMPL_CB *p_cb);
BOOLEAN btm_ble_cancel_remote_name(BD_ADDR remote_bda);

View File

@ -489,6 +489,7 @@ typedef struct {
tBTM_LE_KEY_TYPE key_type; /* bit mask of valid key types in record */
tBTM_SEC_BLE_KEYS keys; /* LE device security info in slave rode */
bool skip_update_conn_param; /* skip update connection paraams or not*/
UINT16 auth_mode; /* Authentication mode */
#endif
#if (BLE_PRIVACY_SPT == TRUE)
tBLE_ADDR_TYPE current_addr_type; /* current adv addr type*/

View File

@ -122,6 +122,7 @@ static void btu_hcif_ssr_evt (UINT8 *p, UINT16 evt_len);
#if BLE_INCLUDED == TRUE
static void btu_ble_ll_conn_complete_evt (UINT8 *p, UINT16 evt_len);
static void btu_ble_process_adv_pkt (UINT8 *p);
static void btu_ble_process_adv_dis(UINT8 *p);
static void btu_ble_read_remote_feat_evt (UINT8 *p);
static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len);
static void btu_ble_ll_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handle);
@ -331,6 +332,9 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
case HCI_BLE_ADV_PKT_RPT_EVT: /* result of inquiry */
btu_ble_process_adv_pkt(p);
break;
case HCI_BLE_ADV_DISCARD_REPORT_EVT:
btu_ble_process_adv_dis(p);
break;
case HCI_BLE_CONN_COMPLETE_EVT:
btu_ble_ll_conn_complete_evt(p, hci_evt_len);
break;
@ -1764,6 +1768,11 @@ static void btu_ble_process_adv_pkt (UINT8 *p)
btm_ble_process_adv_pkt(p);
}
static void btu_ble_process_adv_dis(UINT8 *p)
{
btm_ble_process_adv_discard_evt(p);
}
static void btu_ble_ll_conn_complete_evt ( UINT8 *p, UINT16 evt_len)
{
btm_ble_conn_complete(p, evt_len, FALSE);

View File

@ -188,6 +188,8 @@ void gatt_free(void)
#if (GATTS_INCLUDED == TRUE)
for (i = 0; i < GATT_MAX_SR_PROFILES; i++) {
gatt_remove_an_item_from_list(&gatt_cb.hdl_list_info, &gatt_cb.hdl_list[i]);
gatt_free_attr_value_buffer(&gatt_cb.hdl_list[i]);
gatt_free_hdl_buffer(&gatt_cb.hdl_list[i]);
}
#endif /* #if (GATTS_INCLUDED == TRUE) */

View File

@ -1595,8 +1595,10 @@ void gatts_process_value_conf(tGATT_TCB *p_tcb, UINT8 op_code)
if (p_rcb->in_use && p_rcb->s_hdl <= handle && p_rcb->e_hdl >= handle) {
trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle);
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_rcb->gatt_if);
tGATTS_DATA p_data = {0};
p_data.handle = handle;
gatt_sr_send_req_callback(conn_id,
trans_id, GATTS_REQ_TYPE_CONF, (tGATTS_DATA *)&handle);
trans_id, GATTS_REQ_TYPE_CONF, &p_data);
}
}
}

View File

@ -999,5 +999,27 @@ BOOLEAN btsnd_hcic_ble_set_data_length(UINT16 conn_handle, UINT16 tx_octets, UIN
return TRUE;
}
BOOLEAN btsnd_hcic_ble_update_adv_report_flow_control (UINT16 num)
{
BT_HDR *p;
UINT8 *pp;
if ((p = HCI_GET_CMD_BUF (1)) == NULL) {
return (FALSE);
}
pp = (UINT8 *)(p + 1);
p->len = HCIC_PREAMBLE_SIZE + 2;
p->offset = 0;
UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_ADV_REPORT_FLOW_CONTROL);
UINT8_TO_STREAM (pp, 2);
UINT16_TO_STREAM (pp, num);
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
return TRUE;
}
#endif

View File

@ -790,4 +790,22 @@ static inline void bdsetany(BD_ADDR a)
{
bdcpy(a, bd_addr_any);
}
/*******************************************************************************
**
** Function bt_rcopy
**
** Description memory reverse and copy.
**
**
** Returns void
**
*******************************************************************************/
static inline void bt_rcopy(UINT8 *dst, UINT8 const *src, UINT16 len)
{
src += len;
while (len --) {
*dst++ = *--src;
}
}
#endif

View File

@ -169,6 +169,8 @@ typedef void (tBTM_VS_EVT_CB) (UINT8 len, UINT8 *p);
*/
typedef void (tBTM_CMPL_CB) (void *p1);
typedef void (tBTM_INQ_DIS_CB) (uint32_t num_dis);
/* VSC callback function for notifying an application that a synchronous
** BTM function is complete. The pointer contains the address of any returned data.
*/
@ -677,7 +679,6 @@ typedef struct {
UINT8 num_resp; /* Number of results from the current inquiry */
} tBTM_INQUIRY_CMPL;
/* Structure returned with remote name request */
typedef struct {
UINT16 status;

View File

@ -867,6 +867,7 @@ tBTM_BLE_SCAN_SETUP_CBACK bta_ble_scan_setup_cb;
typedef void (tBTM_START_ADV_CMPL_CBACK) (UINT8 status);
typedef void (tBTM_START_STOP_ADV_CMPL_CBACK) (UINT8 status);
typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info);
/*****************************************************************************
@ -903,13 +904,14 @@ void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn
** bd_name - Name of the peer device. NULL if unknown.
** dev_type - Remote device's device type.
** addr_type - LE device address type.
** auth_mode - auth mode
**
** Returns TRUE if added OK, else FALSE
**
*******************************************************************************/
//extern
BOOLEAN BTM_SecAddBleDevice (BD_ADDR bd_addr, BD_NAME bd_name,
tBT_DEVICE_TYPE dev_type, tBLE_ADDR_TYPE addr_type);
tBT_DEVICE_TYPE dev_type, tBLE_ADDR_TYPE addr_type, UINT32 auth_mode);
/*******************************************************************************
**
@ -1241,7 +1243,7 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT32 duration,
*******************************************************************************/
//extern
tBTM_STATUS BTM_BleScan(BOOLEAN start, UINT32 duration,
tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb);
tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb, tBTM_INQ_DIS_CB *p_discard_cb);
/*******************************************************************************
@ -2052,6 +2054,22 @@ tBTM_STATUS BTM_BleGetEnergyInfo(tBTM_BLE_ENERGY_INFO_CBACK *p_ener_cback);
//extern
tBTM_STATUS BTM_SetBleDataLength(BD_ADDR bd_addr, UINT16 tx_pdu_length);
/*******************************************************************************
**
** Function BTM_UpdateBleDuplicateExceptionalList
**
** Description This function is called to update duplicate scan exceptional list.
**
** Parameters: subcode: add, remove or clean duplicate scan exceptional list.
** type: device info type
** device_info: device information
** update_exceptional_list_cmp_cb: complete callback
**
** Returns status
**
*******************************************************************************/
tBTM_STATUS BTM_UpdateBleDuplicateExceptionalList(uint8_t subcode, uint32_t type, BD_ADDR device_info, tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK update_exceptional_list_cmp_cb);
/*
#ifdef __cplusplus
}

View File

@ -51,6 +51,7 @@
#define SLIP_DYNAMIC_MEMORY TRUE
#define LLCP_DYNAMIC_MEMORY TRUE
#define BTC_SBC_DEC_DYNAMIC_MEMORY TRUE
#define BTC_SBC_ENC_DYNAMIC_MEMORY TRUE
#else /* #if CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY */
@ -79,6 +80,7 @@
#define SLIP_DYNAMIC_MEMORY FALSE
#define LLCP_DYNAMIC_MEMORY FALSE
#define BTC_SBC_DEC_DYNAMIC_MEMORY FALSE
#define BTC_SBC_ENC_DYNAMIC_MEMORY FALSE
#endif /* #if CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY */
/****************************************************************************

View File

@ -45,7 +45,7 @@
#define HCI_GRP_VENDOR_SPECIFIC (0x3F << 10) /* 0xFC00 */
/* Group occupies high 6 bits of the HCI command rest is opcode itself */
#define HCI_OGF(p) (UINT8)((0xFC00 & (p)) >> 10)
#define HCI_OGF(p) (UINT8)(0x003F & (p >> 10))
#define HCI_OCF(p) ( 0x3FF & (p))
/*
@ -352,27 +352,74 @@
#define HCI_BLE_READ_RESOLVABLE_ADDR_LOCAL (0x002C | HCI_GRP_BLE_CMDS)
#define HCI_BLE_SET_ADDR_RESOLUTION_ENABLE (0x002D | HCI_GRP_BLE_CMDS)
#define HCI_BLE_SET_RAND_PRIV_ADDR_TIMOUT (0x002E | HCI_GRP_BLE_CMDS)
// Vendor OGF define
#define HCI_VENDOR_OGF 0x3F
/* LE Get Vendor Capabilities Command OCF */
#define HCI_BLE_VENDOR_CAP_OCF (0x0153 | HCI_GRP_VENDOR_SPECIFIC)
// ESP vendor group define
#define HCI_ESP_GROUP_COMMON 0x01
#define HCI_ESP_GROUP_BLE 0x02
#define HCI_ESP_GROUP_BT 0x03
#define HCI_ESP_GROUP_END 0x07
//ESP common subcode define
#define HCI_SUBCODE_COMMON_INIT 0x00
#define HCI_SUBCODE_COMMON_ECHO 0x01
#define HCI_SUBCODE_COMMON_MAX 0x7F
//ESP BLE subcode define
#define HCI_SUBCODE_BLE_INIT 0x00
#define HCI_SUBCODE_BLE_MULTI_ADV 0x01
#define HCI_SUBCODE_BLE_BATCH_SCAN 0x02
#define HCI_SUBCODE_BLE_ADV_FILTER 0x03
#define HCI_SUBCODE_BLE_TRACK_ADV 0x04
#define HCI_SUBCODE_BLE_ENERGY_INFO 0x05
#define HCI_SUBCODE_BLE_EXTENDED_SCAN_PARAMS 0x06
#define HCI_SUBCODE_BLE_LONG_ADV 0x07
#define HCI_SUBCODE_BLE_DUPLICATE_EXCEPTIONAL_LIST 0x08
#define HCI_SUBCODE_BLE_SET_ADV_FLOW_CONTROL 0x09
#define HCI_SUBCODE_BLE_ADV_REPORT_FLOW_CONTROL 0x0A
#define HCI_SUBCODE_BLE_MAX 0x7F
//ESP BT subcode define
#define HCI_SUBCODE_BT_INIT 0x00
#define HCI_SUBCODE_BT_MAX 0x7F
#define HCI_ESP_VENDOR_OPCODE_BUILD(ogf, group, subcode) ((ogf << 10) | (group <<7) | (subcode << 0))
/*
* | OGF | VENDIOR GROUP | GROUP SUBCODE |
* | 1 1 1 1 1 1 | 0 0 0 | X X X X X X X | Already Exist
* | 1 1 1 1 1 1 | 0 0 1 | X X X X X X X | ESP VENDOR COMMON HCI CMD
* | 1 1 1 1 1 1 | 0 1 0 | X X X X X X X | ESP VENDOR BLE HCI CMD
* | 1 1 1 1 1 1 | 0 1 1 | X X X X X X X | ESP VENDOR BT HCI CMD
* | 1 1 1 1 1 1 | 1 0 0 | X X X X X X X | RESERVED FOR FUTURE USE
* | 1 1 1 1 1 1 | 1 0 1 | X X X X X X X | RESERVED FOR FUTURE USE
* | 1 1 1 1 1 1 | 1 1 0 | X X X X X X X | RESERVED FOR FUTURE USE
* | 1 1 1 1 1 1 | 1 1 1 | X X X X X X X | RESERVED FOR FUTURE USE
*/
// ESP COMMON HCI CMD
#define HCI_VENDOR_COMMON_ECHO_CMD_OPCODE HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_COMMON, HCI_SUBCODE_COMMON_ECHO)
//ESP BLE HCI CMD
/* Multi adv OCF */
#define HCI_BLE_MULTI_ADV_OCF (0x0154 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_BLE_MULTI_ADV_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_COMMON, HCI_SUBCODE_BLE_MULTI_ADV)
/* Batch scan OCF */
#define HCI_BLE_BATCH_SCAN_OCF (0x0156 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_BLE_BATCH_SCAN_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_COMMON, HCI_SUBCODE_BLE_BATCH_SCAN)
/* ADV filter OCF */
#define HCI_BLE_ADV_FILTER_OCF (0x0157 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_BLE_ADV_FILTER_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_COMMON, HCI_SUBCODE_BLE_ADV_FILTER)
/* Tracking OCF */
#define HCI_BLE_TRACK_ADV_OCF (0x0158 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_BLE_TRACK_ADV_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_COMMON, HCI_SUBCODE_BLE_TRACK_ADV)
/* Energy info OCF */
#define HCI_BLE_ENERGY_INFO_OCF (0x0159 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_BLE_ENERGY_INFO_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_COMMON, HCI_SUBCODE_BLE_ENERGY_INFO)
/* Extended BLE Scan parameters OCF */
#define HCI_BLE_EXTENDED_SCAN_PARAMS_OCF (0x0160 | HCI_GRP_VENDOR_SPECIFIC)
#define HCI_BLE_EXTENDED_SCAN_PARAMS_OCF HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_EXTENDED_SCAN_PARAMS)
/* Long BLE Adv data OCF */
#define HCI_VENDOR_BLE_LONG_ADV_DATA HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_LONG_ADV)
/* BLE update duplicate scan exceptional list */
#define HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_DUPLICATE_EXCEPTIONAL_LIST)
#define HCI_VENDOR_BLE_SET_ADV_FLOW_CONTROL HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_SET_ADV_FLOW_CONTROL)
#define HCI_VENDOR_BLE_ADV_REPORT_FLOW_CONTROL HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_ADV_REPORT_FLOW_CONTROL)
//ESP BT HCI CMD
/* subcode for multi adv feature */
#define BTM_BLE_MULTI_ADV_SET_PARAM 0x01
@ -706,6 +753,8 @@
#define HCI_BLE_DATA_LENGTH_CHANGE_EVT 0x07
#define HCI_BLE_ENHANCED_CONN_COMPLETE_EVT 0x0a
#define HCI_BLE_DIRECT_ADV_EVT 0x0b
/* ESP vendor BLE Event sub code */
#define HCI_BLE_ADV_DISCARD_REPORT_EVT 0XF0
/* Definitions for LE Channel Map */
#define HCI_BLE_CHNL_MAP_SIZE 5

View File

@ -555,6 +555,10 @@ BOOLEAN btsnd_hcic_write_voice_settings(UINT16 flags); /* Write Voice
#define HCI_HOST_FLOW_CTRL_SCO_ON 2
#define HCI_HOST_FLOW_CTRL_BOTH_ON 3
#define HCI_HOST_FLOW_CTRL_ADV_REPORT_OFF 0
#define HCI_HOST_FLOW_CTRL_ADV_REPORT_ON 1
BOOLEAN btsnd_hcic_write_auto_flush_tout(UINT16 handle,
UINT16 timeout); /* Write Retransmit Timout */
@ -806,6 +810,8 @@ BOOLEAN btsnd_hcic_read_authenticated_payload_tout(UINT16 handle);
BOOLEAN btsnd_hcic_write_authenticated_payload_tout(UINT16 handle,
UINT16 timeout);
BOOLEAN btsnd_hcic_ble_update_adv_report_flow_control (UINT16 num);
#define HCIC_PARAM_SIZE_WRITE_AUTHENT_PAYLOAD_TOUT 4
#define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_HANDLE_OFF 0

View File

@ -1845,7 +1845,7 @@ BOOLEAN L2CA_CheckIsCongest(UINT16 fixed_cid, UINT16 handle)
tL2C_LCB *p_lcb;
p_lcb = l2cu_find_lcb_by_handle(handle);
if (p_lcb != NULL) {
if (p_lcb != NULL && p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] != NULL) {
return p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent;
}

View File

@ -813,17 +813,17 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
memcpy(peer_addr, p_dev_rec->ble.current_addr, 6);
} else {
/* find security device information but not find the real address information
* This state may be directly open whithout scanning. In this case, you must
* This state may be directly open without scanning. In this case, you must
* use the current adv address of the device to open*/
}
}
} else {
//not find security device information, We think this is a new device, connect directly
}
/* It will cause that scanner doesn't send scan request to advertiser
* which has sent IRK to us and we have stored the IRK in controller.
* It is a design problem of hardware. The temporal solution is not to
* send the key to the controller and then resolve the random address in host.
* It is a hardware limitation. The preliminary solution is not to
* send key to the controller, but to resolve the random address in host.
* so we need send the real address information to controller. */
/*
if (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) {

View File

@ -596,6 +596,7 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
}
reason = SMP_PAIR_AUTH_FAIL;
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
return;
}
}
@ -624,7 +625,7 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
if(p_cb->peer_auth_req & p_cb->loc_auth_req & SMP_AUTH_GEN_BOND) {
auth |= SMP_AUTH_GEN_BOND;
}
p_cb->auth_mode = auth;
p_cb->auth_mode = auth;
if (p_cb->accept_specified_sec_auth) {
if ((auth & p_cb->origin_loc_auth_req) != p_cb->origin_loc_auth_req ) {
SMP_TRACE_ERROR("%s pairing failed - master requires auth is 0x%x but peer auth is 0x%x local auth is 0x%x",
@ -634,6 +635,7 @@ void smp_proc_pair_cmd(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
}
reason = SMP_PAIR_AUTH_FAIL;
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
return;
}
}
@ -1363,7 +1365,6 @@ void smp_decide_association_model(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
void smp_process_io_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
uint8_t reason = SMP_PAIR_AUTH_FAIL;
SMP_TRACE_DEBUG("%s\n", __func__);
if (p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD) {
/* pairing started by local (slave) Security Request */
@ -1395,6 +1396,7 @@ void smp_process_io_response(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
}
reason = SMP_PAIR_AUTH_FAIL;
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
return;
}
}

View File

@ -964,7 +964,7 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb)
tSMP_EVT_DATA evt_data = {0};
tSMP_CALLBACK *p_callback = p_cb->p_callback;
BD_ADDR pairing_bda;
tBTM_SEC_DEV_REC *p_rec;
tBTM_SEC_DEV_REC *p_rec = btm_find_dev (p_cb->pairing_bda);
SMP_TRACE_DEBUG ("smp_proc_pairing_cmpl \n");
@ -973,7 +973,14 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb)
evt_data.cmplt.auth_mode = 0;
if (p_cb->status == SMP_SUCCESS) {
evt_data.cmplt.sec_level = p_cb->sec_level;
evt_data.cmplt.auth_mode = p_cb->auth_mode;
if (p_cb->auth_mode) { // the first encryption
evt_data.cmplt.auth_mode = p_cb->auth_mode;
if (p_rec) {
p_rec->ble.auth_mode = p_cb->auth_mode;
}
} else if (p_rec) {
evt_data.cmplt.auth_mode = p_rec->ble.auth_mode;
}
}
evt_data.cmplt.is_pair_cancel = FALSE;
@ -990,7 +997,6 @@ void smp_proc_pairing_cmpl(tSMP_CB *p_cb)
memcpy (pairing_bda, p_cb->pairing_bda, BD_ADDR_LEN);
if (p_cb->role == HCI_ROLE_SLAVE) {
p_rec = btm_find_dev (p_cb->pairing_bda);
if(p_rec && p_rec->ble.skip_update_conn_param) {
//clear flag
p_rec->ble.skip_update_conn_param = false;

View File

@ -65,7 +65,7 @@
/* Sleep mode */
#define BTDM_MODEM_SLEEP_MODE_NONE (0)
#define BTDM_MODEM_SLEEP_MODE_ORIG (1)
#define BTDM_MODEM_SLEEP_MODE_EVED (2)
#define BTDM_MODEM_SLEEP_MODE_EVED (2) // sleep mode for BLE controller, used only for internal test.
/* Low Power Clock Selection */
#define BTDM_LPCLK_SEL_XTAL (0)
@ -73,8 +73,9 @@
#define BTDM_LPCLK_SEL_RTC_SLOW (2)
#define BTDM_LPCLK_SEL_8M (3)
/* Sleep duration */
#define BTDM_MIN_SLEEP_DURATION (20)
/* Sleep and wakeup interval control */
#define BTDM_MIN_SLEEP_DURATION (12) // threshold of interval in slots to allow to fall into modem sleep
#define BTDM_MODEM_WAKE_UP_DELAY (4) // delay in slots of modem wake up procedure, including re-enable PHY/RF
#define BT_DEBUG(...)
#define BT_API_CALL_CHECK(info, api_call, ret) \
@ -159,8 +160,11 @@ struct osi_funcs_t {
uint32_t (* _btdm_lpcycles_2_us)(uint32_t cycles);
uint32_t (* _btdm_us_2_lpcycles)(uint32_t us);
bool (* _btdm_sleep_check_duration)(uint32_t *slot_cnt);
void (* _btdm_sleep_enter)(void);
void (* _btdm_sleep_exit)(void); /* called from ISR */
void (* _btdm_sleep_enter_phase1)(uint32_t lpcycles); /* called when interrupt is disabled */
void (* _btdm_sleep_enter_phase2)(void);
void (* _btdm_sleep_exit_phase1)(void); /* called from ISR */
void (* _btdm_sleep_exit_phase2)(void); /* called from ISR */
void (* _btdm_sleep_exit_phase3)(void); /* called from task */
uint32_t _magic;
};
@ -179,7 +183,7 @@ extern int btdm_controller_enable(esp_bt_mode_t mode);
extern void btdm_controller_disable(void);
extern uint8_t btdm_controller_get_mode(void);
extern const char *btdm_controller_get_compile_version(void);
extern void btdm_rf_bb_init(void);
extern void btdm_rf_bb_init_phase2(void); // shall be called after PHY/RF is enabled
/* Sleep */
extern void btdm_controller_enable_sleep(bool enable);
extern void btdm_controller_set_sleep_mode(uint8_t mode);
@ -255,8 +259,10 @@ static int IRAM_ATTR rand_wrapper(void);
static uint32_t IRAM_ATTR btdm_lpcycles_2_us(uint32_t cycles);
static uint32_t IRAM_ATTR btdm_us_2_lpcycles(uint32_t us);
static bool IRAM_ATTR btdm_sleep_check_duration(uint32_t *slot_cnt);
static void IRAM_ATTR btdm_sleep_enter_wrapper(void);
static void IRAM_ATTR btdm_sleep_exit_wrapper(void);
static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles);
static void btdm_sleep_enter_phase2_wrapper(void);
static void IRAM_ATTR btdm_sleep_exit_phase1_wrapper(void);
static void btdm_sleep_exit_phase3_wrapper(void);
/* Local variable definition
***************************************************************************
@ -299,8 +305,11 @@ static const struct osi_funcs_t osi_funcs_ro = {
._btdm_lpcycles_2_us = btdm_lpcycles_2_us,
._btdm_us_2_lpcycles = btdm_us_2_lpcycles,
._btdm_sleep_check_duration = btdm_sleep_check_duration,
._btdm_sleep_enter = btdm_sleep_enter_wrapper,
._btdm_sleep_exit = btdm_sleep_exit_wrapper,
._btdm_sleep_enter_phase1 = btdm_sleep_enter_phase1_wrapper,
._btdm_sleep_enter_phase2 = btdm_sleep_enter_phase2_wrapper,
._btdm_sleep_exit_phase1 = btdm_sleep_exit_phase1_wrapper,
._btdm_sleep_exit_phase2 = NULL,
._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper,
._magic = OSI_MAGIC_VALUE,
};
@ -325,27 +334,42 @@ SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_BSS_START, SOC_MEM_BT_BSS_END,
SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_MISC_START, SOC_MEM_BT_MISC_END, rom_bt_misc);
SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_DATA_START, SOC_MEM_BT_DATA_END, rom_bt_data);
static struct osi_funcs_t *osi_funcs_p;
static DRAM_ATTR struct osi_funcs_t *osi_funcs_p;
#if CONFIG_SPIRAM_USE_MALLOC
static btdm_queue_item_t btdm_queue_table[BTDM_MAX_QUEUE_NUM];
SemaphoreHandle_t btdm_queue_table_mux = NULL;
static DRAM_ATTR btdm_queue_item_t btdm_queue_table[BTDM_MAX_QUEUE_NUM];
static DRAM_ATTR SemaphoreHandle_t btdm_queue_table_mux = NULL;
#endif /* #if CONFIG_SPIRAM_USE_MALLOC */
/* Static variable declare */
static bool btdm_bb_init_flag = false;
static esp_bt_controller_status_t btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
// timestamp when PHY/RF was switched on
static DRAM_ATTR int64_t s_time_phy_rf_just_enabled = 0;
static DRAM_ATTR esp_bt_controller_status_t btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;
static DRAM_ATTR portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;
// measured average low power clock period in micro seconds
static uint32_t btdm_lpcycle_us = 0;
static uint8_t btdm_lpcycle_us_frac = 0; // number of fractional bit for btdm_lpcycle_us
static DRAM_ATTR uint32_t btdm_lpcycle_us = 0;
static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0; // number of fractional bit for btdm_lpcycle_us
#ifdef CONFIG_PM_ENABLE
static esp_pm_lock_handle_t s_pm_lock;
static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr;
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock; // pm_lock to prevent light sleep due to incompatibility currently
static DRAM_ATTR QueueHandle_t s_pm_lock_sem = NULL;
#endif
static inline void btdm_check_and_init_bb(void)
{
/* init BT-BB if PHY/RF has been switched off since last BT-BB init */
int64_t latest_ts = esp_phy_rf_get_on_ts();
if (latest_ts != s_time_phy_rf_just_enabled ||
s_time_phy_rf_just_enabled == 0) {
btdm_rf_bb_init_phase2();
s_time_phy_rf_just_enabled = latest_ts;
}
}
#if CONFIG_SPIRAM_USE_MALLOC
static bool btdm_queue_generic_register(const btdm_queue_item_t *queue)
{
@ -728,7 +752,7 @@ static int IRAM_ATTR rand_wrapper(void)
static uint32_t IRAM_ATTR btdm_lpcycles_2_us(uint32_t cycles)
{
// The number of lp cycles should not lead to overflow. Thrs: 100s (for 32kHz freq)
// The number of lp cycles should not lead to overflow. Thrs: 100s
// clock measurement is conducted
uint64_t us = (uint64_t)btdm_lpcycle_us * cycles;
us = (us + (1 << (btdm_lpcycle_us_frac - 1))) >> btdm_lpcycle_us_frac;
@ -753,16 +777,41 @@ static bool IRAM_ATTR btdm_sleep_check_duration(uint32_t *slot_cnt)
if (*slot_cnt < BTDM_MIN_SLEEP_DURATION) {
return false;
}
/* wake up 3 slots in advance */
*slot_cnt = *slot_cnt -3;
/* wake up in advance considering the delay in enabling PHY/RF */
*slot_cnt -= BTDM_MODEM_WAKE_UP_DELAY;
return true;
}
static void IRAM_ATTR btdm_sleep_enter_wrapper(void)
static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
{
#ifdef CONFIG_PM_ENABLE
// start a timer to wake up and acquire the pm_lock before modem_sleep awakes
uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles);
#define BTDM_MIN_TIMER_UNCERTAINTY_US (1800)
assert(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
// allow a maximum time uncertainty to be about 488ppm(1/2048) at least as clock drift
// and set the timer in advance
uint32_t uncertainty = (us_to_sleep >> 11);
if (uncertainty < BTDM_MIN_TIMER_UNCERTAINTY_US) {
uncertainty = BTDM_MIN_TIMER_UNCERTAINTY_US;
}
if (esp_timer_start_once(s_btdm_slp_tmr, us_to_sleep - uncertainty) != ESP_OK) {
ESP_LOGW(BTDM_LOG_TAG, "timer start failed");
}
#endif
}
static void btdm_sleep_enter_phase2_wrapper(void)
{
if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
esp_modem_sleep_enter(MODEM_BLE_MODULE);
esp_modem_sleep_enter(MODEM_CLASSIC_BT_MODULE);
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_release(s_pm_lock);
semphr_give_wrapper(s_pm_lock_sem);
#endif
} else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
esp_modem_sleep_enter(MODEM_BLE_MODULE);
// pause bluetooth baseband
@ -770,11 +819,24 @@ static void IRAM_ATTR btdm_sleep_enter_wrapper(void)
}
}
static void IRAM_ATTR btdm_sleep_exit_wrapper(void)
static void IRAM_ATTR btdm_sleep_exit_phase1_wrapper(void)
{
#ifdef CONFIG_PM_ENABLE
if (semphr_take_from_isr_wrapper(s_pm_lock_sem, NULL) == pdTRUE) {
esp_pm_lock_acquire(s_pm_lock);
}
#endif
}
static void btdm_sleep_exit_phase3_wrapper(void)
{
if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
esp_modem_sleep_exit(MODEM_BLE_MODULE);
esp_modem_sleep_exit(MODEM_CLASSIC_BT_MODULE);
btdm_check_and_init_bb();
#ifdef CONFIG_PM_ENABLE
esp_timer_stop(s_btdm_slp_tmr);
#endif
} else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
// resume bluetooth baseband
periph_module_enable(PERIPH_BT_BASEBAND_MODULE);
@ -782,6 +844,15 @@ static void IRAM_ATTR btdm_sleep_exit_wrapper(void)
}
}
#ifdef CONFIG_PM_ENABLE
static void IRAM_ATTR btdm_slp_tmr_callback(void *arg)
{
if (semphr_take_wrapper(s_pm_lock_sem, 0) == pdTRUE) {
esp_pm_lock_acquire(s_pm_lock);
}
}
#endif
bool esp_vhci_host_check_send_available(void)
{
return API_vhci_host_check_send_available();
@ -790,6 +861,12 @@ bool esp_vhci_host_check_send_available(void)
void esp_vhci_host_send_packet(uint8_t *data, uint16_t len)
{
if (!btdm_power_state_active()) {
#if CONFIG_PM_ENABLE
if (semphr_take_wrapper(s_pm_lock_sem, 0)) {
esp_pm_lock_acquire(s_pm_lock);
}
esp_timer_stop(s_btdm_slp_tmr);
#endif
btdm_wakeup_request();
}
API_vhci_host_send_packet(data, len);
@ -942,7 +1019,7 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
{
BaseType_t ret;
esp_err_t err;
uint32_t btdm_cfg_mask = 0;
osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t));
@ -983,27 +1060,39 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
return ESP_ERR_INVALID_ARG;
}
#ifdef CONFIG_PM_ENABLE
esp_err_t err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock);
if (err != ESP_OK) {
return err;
}
#endif
ESP_LOGI(BTDM_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version());
#if CONFIG_SPIRAM_USE_MALLOC
btdm_queue_table_mux = xSemaphoreCreateMutex();
if (btdm_queue_table == NULL) {
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_delete(s_pm_lock);
s_pm_lock = NULL;
#endif
if (btdm_queue_table_mux == NULL) {
return ESP_ERR_NO_MEM;
}
memset(btdm_queue_table, 0, sizeof(btdm_queue_item_t) * BTDM_MAX_QUEUE_NUM);
#endif
#ifdef CONFIG_PM_ENABLE
if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
goto error;
}
if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) {
goto error;
}
esp_timer_create_args_t create_args = {
.callback = btdm_slp_tmr_callback,
.arg = NULL,
.name = "btSlp"
};
if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) {
goto error;
}
s_pm_lock_sem = semphr_create_wrapper(1, 0);
if (s_pm_lock_sem == NULL) {
err = ESP_ERR_NO_MEM;
goto error;
}
#endif
btdm_controller_mem_init();
periph_module_enable(PERIPH_BT_MODULE);
@ -1015,10 +1104,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
bool set_div_ret = false;
#if CONFIG_BTDM_LPCLK_SEL_MAIN_XTAL
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL);
set_div_ret = btdm_lpclk_set_div(rtc_clk_xtal_freq_get() * 32 - 1);
set_div_ret = btdm_lpclk_set_div(rtc_clk_xtal_freq_get() * 2 - 1);
assert(select_src_ret && set_div_ret);
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = 32 << btdm_lpcycle_us_frac;
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
#elif CONFIG_BTDM_LPCLK_SEL_EXT_32K_XTAL
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K);
set_div_ret = btdm_lpclk_set_div(0);
@ -1036,17 +1125,35 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
btdm_cfg_mask = btdm_config_mask_load();
ret = btdm_controller_init(btdm_cfg_mask, cfg);
if (ret) {
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_delete(s_pm_lock);
s_pm_lock = NULL;
#endif
return ESP_ERR_NO_MEM;
if (btdm_controller_init(btdm_cfg_mask, cfg) != 0) {
err = ESP_ERR_NO_MEM;
goto error;
}
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
return ESP_OK;
error:
#ifdef CONFIG_PM_ENABLE
if (s_light_sleep_pm_lock != NULL) {
esp_pm_lock_delete(s_light_sleep_pm_lock);
s_light_sleep_pm_lock = NULL;
}
if (s_pm_lock != NULL) {
esp_pm_lock_delete(s_pm_lock);
s_pm_lock = NULL;
}
if (s_btdm_slp_tmr != NULL) {
esp_timer_delete(s_btdm_slp_tmr);
s_btdm_slp_tmr = NULL;
}
if (s_pm_lock_sem) {
semphr_delete_wrapper(s_pm_lock_sem);
s_pm_lock_sem = NULL;
}
#endif
return err;
}
esp_err_t esp_bt_controller_deinit(void)
@ -1059,6 +1166,18 @@ esp_err_t esp_bt_controller_deinit(void)
periph_module_disable(PERIPH_BT_MODULE);
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_delete(s_light_sleep_pm_lock);
s_light_sleep_pm_lock = NULL;
esp_pm_lock_delete(s_pm_lock);
s_pm_lock = NULL;
esp_timer_stop(s_btdm_slp_tmr);
esp_timer_delete(s_btdm_slp_tmr);
s_btdm_slp_tmr = NULL;
semphr_delete_wrapper(s_pm_lock_sem);
s_pm_lock_sem = NULL;
#endif
#if CONFIG_SPIRAM_USE_MALLOC
vSemaphoreDelete(btdm_queue_table_mux);
btdm_queue_table_mux = NULL;
@ -1072,10 +1191,6 @@ esp_err_t esp_bt_controller_deinit(void)
btdm_lpcycle_us = 0;
btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE);
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_delete(s_pm_lock);
s_pm_lock = NULL;
#endif
return ESP_OK;
}
@ -1094,6 +1209,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
}
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_acquire(s_light_sleep_pm_lock);
esp_pm_lock_acquire(s_pm_lock);
#endif
@ -1117,10 +1233,8 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
btdm_controller_enable_sleep(true);
}
if (btdm_bb_init_flag == false) {
btdm_bb_init_flag = true;
btdm_rf_bb_init(); /* only initialise once */
}
// inititalize bluetooth baseband
btdm_check_and_init_bb();
ret = btdm_controller_enable(mode);
if (ret) {
@ -1133,6 +1247,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
}
esp_phy_rf_deinit(PHY_BT_MODULE);
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_release(s_light_sleep_pm_lock);
esp_pm_lock_release(s_pm_lock);
#endif
return ESP_ERR_INVALID_STATE;
@ -1173,6 +1288,7 @@ esp_err_t esp_bt_controller_disable(void)
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_release(s_light_sleep_pm_lock);
esp_pm_lock_release(s_pm_lock);
#endif

View File

@ -326,8 +326,12 @@ bool esp_vhci_host_check_send_available(void);
/** @brief esp_vhci_host_send_packet
* host send packet to controller
*
* Should not call this function from within a critical section
* or when the scheduler is suspended.
*
* @param data the packet point
*,@param len the packet length
* @param len the packet length
*/
void esp_vhci_host_send_packet(uint8_t *data, uint16_t len);
@ -405,7 +409,6 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode);
*
* For ORIG mode:
* Bluetooth modem sleep is enabled in controller start up by default if CONFIG_BTDM_CONTROLLER_MODEM_SLEEP is set and "ORIG mode" is selected. In ORIG modem sleep mode, bluetooth controller will switch off some components and pause to work every now and then, if there is no event to process; and wakeup according to the scheduled interval and resume the work. It can also wakeup earlier upon external request using function "esp_bt_controller_wakeup_request".
* Note that currently there is problem in the combination use of bluetooth modem sleep and Dynamic Frequency Scaling(DFS). So do not enable DFS if bluetooth modem sleep is in use.
*
* @return
* - ESP_OK : success
@ -454,11 +457,11 @@ void esp_bt_controller_wakeup_request(void);
/**
* @brief Manually clear scan duplicate list
*
*
* Note that scan duplicate list will be automatically cleared when the maximum amount of device in the filter is reached
* the amount of device in the filter can be configured in menuconfig.
*
*
*
*
* @return
* - ESP_OK : success
* - other : failed

View File

@ -106,6 +106,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
@ -879,6 +880,9 @@ static int linenoiseEdit(char *buf, size_t buflen, const char *prompt)
linenoiseEditDeletePrevWord(&l);
break;
}
if (__fbufsize(stdout) > 0) {
fflush(stdout);
}
}
return l.len;
}

View File

@ -41,8 +41,10 @@ config SPI_MASTER_ISR_IN_IRAM
bool "Place SPI master ISR function into IRAM"
default y
help
Place the SPI master ISR in to IRAM to avoid possibly cache miss, or
being disabled during flash writing access.
Place the SPI master ISR in to IRAM to avoid possible cache miss.
Also you can forbid the ISR being disabled during flash writing
access, by add ESP_INTR_FLAG_IRAM when initializing the driver.
config SPI_SLAVE_IN_IRAM
bool "Place transmitting functions of SPI slave into IRAM"
@ -61,8 +63,10 @@ config SPI_SLAVE_ISR_IN_IRAM
bool "Place SPI slave ISR function into IRAM"
default y
help
Place the SPI slave ISR in to IRAM to avoid possibly cache miss, or
being disabled during flash writing access.
Place the SPI slave ISR in to IRAM to avoid possible cache miss.
Also you can forbid the ISR being disabled during flash writing
access, by add ESP_INTR_FLAG_IRAM when initializing the driver.
endmenu # SPI Configuration

View File

@ -539,6 +539,20 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num)
return r == ESP_OK ? ESP_OK : ESP_ERR_NOT_SUPPORTED;
}
void gpio_deep_sleep_hold_en(void)
{
portENTER_CRITICAL(&gpio_spinlock);
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
portEXIT_CRITICAL(&gpio_spinlock);
}
void gpio_deep_sleep_hold_dis(void)
{
portENTER_CRITICAL(&gpio_spinlock);
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
portEXIT_CRITICAL(&gpio_spinlock);
}
void gpio_iomux_in(uint32_t gpio, uint32_t signal_idx)
{
GPIO.func_in_sel_cfg[signal_idx].sig_in_sel = 0;

View File

@ -79,6 +79,9 @@ static DRAM_ATTR i2c_dev_t* const I2C[I2C_NUM_MAX] = { &I2C0, &I2C1 };
#define I2C_SLAVE_SDA_HOLD_DEFAULT (10) /* I2C slave hold time after scl negative edge default value */
#define I2C_MASTER_TOUT_CNUM_DEFAULT (8) /* I2C master timeout cycle number of I2C clock, after which the timeout interrupt will be triggered */
#define I2C_ACKERR_CNT_MAX (10)
#define I2C_FILTER_CYC_NUM_DEF (7) /* The number of apb cycles filtered by default*/
#define I2C_CLR_BUS_SCL_NUM (9)
#define I2C_CLR_BUS_HALF_PERIOD_US (5)
typedef struct {
uint8_t byte_num; /*!< cmd byte number */
@ -524,7 +527,9 @@ esp_err_t i2c_get_data_mode(i2c_port_t i2c_num, i2c_trans_mode_t *tx_trans_mode,
static esp_err_t i2c_master_clear_bus(i2c_port_t i2c_num)
{
I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
const int scl_half_period = I2C_CLR_BUS_HALF_PERIOD_US; // use standard 100kHz data rate
int sda_in_sig = 0, scl_in_sig = 0;
int i = 0;
if (i2c_num == I2C_NUM_0) {
sda_in_sig = I2CEXT0_SDA_IN_IDX;
scl_in_sig = I2CEXT0_SCL_IN_IDX;
@ -535,19 +540,27 @@ static esp_err_t i2c_master_clear_bus(i2c_port_t i2c_num)
int scl_io = GPIO.func_in_sel_cfg[scl_in_sig].func_sel;
int sda_io = GPIO.func_in_sel_cfg[sda_in_sig].func_sel;
I2C_CHECK((GPIO_IS_VALID_OUTPUT_GPIO(scl_io)), I2C_SCL_IO_ERR_STR, ESP_ERR_INVALID_ARG);
I2C_CHECK((GPIO_IS_VALID_GPIO(sda_io)), I2C_SDA_IO_ERR_STR, ESP_ERR_INVALID_ARG);
// We do not check whether the SDA line is low
// because after some serious interference, the bus may keep high all the time and the i2c bus is out of service.
I2C_CHECK((GPIO_IS_VALID_OUTPUT_GPIO(sda_io)), I2C_SDA_IO_ERR_STR, ESP_ERR_INVALID_ARG);
gpio_set_direction(scl_io, GPIO_MODE_OUTPUT_OD);
gpio_set_direction(sda_io, GPIO_MODE_OUTPUT_OD);
gpio_set_level(scl_io, 1);
gpio_set_direction(sda_io, GPIO_MODE_INPUT_OUTPUT_OD);
// 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 READ byte 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.
// So, this reset code needs to synchronize the bit stream with, Either, the ACK bit, Or a 1 bit to correctly generate
// a STOP condition.
gpio_set_level(scl_io, 0);
gpio_set_level(sda_io, 1);
gpio_set_level(sda_io, 0);
for (int i = 0; i < 9; i++) {
gpio_set_level(scl_io, 0);
ets_delay_us(scl_half_period);
while(!gpio_get_level(sda_io) && (i++ < I2C_CLR_BUS_SCL_NUM)) {
gpio_set_level(scl_io, 1);
ets_delay_us(scl_half_period);
gpio_set_level(scl_io, 0);
ets_delay_us(scl_half_period);
}
gpio_set_level(sda_io, 1);
gpio_set_level(sda_io,0); // setup for STOP
gpio_set_level(scl_io,1);
ets_delay_us(scl_half_period);
gpio_set_level(sda_io, 1); // STOP, SDA low -> high while SCL is HIGH
i2c_set_pin(i2c_num, sda_io, scl_io, 1, 1, I2C_MODE_MASTER);
return ESP_OK;
}
@ -660,6 +673,8 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t* i2c_conf)
//set timing for stop signal
I2C[i2c_num]->scl_stop_hold.time = half_cycle;
I2C[i2c_num]->scl_stop_setup.time = half_cycle;
//Default, we enable hardware filter
i2c_filter_enable(i2c_num, I2C_FILTER_CYC_NUM_DEF);
}
I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
@ -693,6 +708,28 @@ esp_err_t i2c_get_period(i2c_port_t i2c_num, int* high_period, int* low_period)
return ESP_OK;
}
esp_err_t i2c_filter_enable(i2c_port_t i2c_num, uint8_t cyc_num)
{
I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
I2C[i2c_num]->scl_filter_cfg.thres = cyc_num;
I2C[i2c_num]->sda_filter_cfg.thres = cyc_num;
I2C[i2c_num]->scl_filter_cfg.en = 1;
I2C[i2c_num]->sda_filter_cfg.en = 1;
I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
return ESP_OK;
}
esp_err_t i2c_filter_disable(i2c_port_t i2c_num)
{
I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
I2C_ENTER_CRITICAL(&i2c_spinlock[i2c_num]);
I2C[i2c_num]->scl_filter_cfg.en = 0;
I2C[i2c_num]->sda_filter_cfg.en = 0;
I2C_EXIT_CRITICAL(&i2c_spinlock[i2c_num]);
return ESP_OK;
}
esp_err_t i2c_set_start_timing(i2c_port_t i2c_num, int setup_time, int hold_time)
{
I2C_CHECK(i2c_num < I2C_NUM_MAX, I2C_NUM_ERROR_STR, ESP_ERR_INVALID_ARG);
@ -1375,4 +1412,4 @@ int i2c_slave_read_buffer(i2c_port_t i2c_num, uint8_t* data, size_t max_size, Ti
}
xSemaphoreGive(p_i2c->slv_rx_mux);
return cnt;
}
}

View File

@ -86,6 +86,7 @@ typedef struct {
i2s_mode_t mode; /*!< I2S Working mode*/
uint32_t sample_rate; /*!< I2S sample rate */
bool use_apll; /*!< I2S use APLL clock */
bool tx_desc_auto_clear; /*!< I2S auto clear tx descriptor on underflow */
int fixed_mclk; /*!< I2S fixed MLCK clock */
} i2s_obj_t;
@ -502,6 +503,12 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg)
// All buffers are empty. This means we have an underflow on our hands.
if (xQueueIsQueueFullFromISR(p_i2s->tx->queue)) {
xQueueReceiveFromISR(p_i2s->tx->queue, &dummy, &high_priority_task_awoken);
// See if tx descriptor needs to be auto cleared:
// This will avoid any kind of noise that may get introduced due to transmission
// of previous data from tx descriptor on I2S line.
if (p_i2s->tx_desc_auto_clear == true) {
memset((void *) dummy, 0, p_i2s->tx->buf_size);
}
}
xQueueSendFromISR(p_i2s->tx->queue, (void*)(&finish_desc->buf), &high_priority_task_awoken);
if (p_i2s->i2s_queue) {
@ -991,6 +998,7 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co
}
p_i2s_obj[i2s_num]->use_apll = i2s_config->use_apll;
p_i2s_obj[i2s_num]->tx_desc_auto_clear = i2s_config->tx_desc_auto_clear;
p_i2s_obj[i2s_num]->fixed_mclk = i2s_config->fixed_mclk;
return ESP_OK;
}

View File

@ -537,13 +537,17 @@ esp_err_t gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t streng
esp_err_t gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t* strength);
/**
* @brief Set gpio pad hold function.
* @brief Enable gpio pad hold function.
*
* The gpio pad hold function works in both input and output modes, but must be output-capable gpios.
* If pad hold enabled:
* in output mode: the output level of the pad will be force locked and can not be changed.
* in input mode: the input value read will not change, regardless the changes of input signal.
*
* The state of digital gpio cannot be held during Deep-sleep, and it will resume the hold function
* when the chip wakes up from Deep-sleep. If the digital gpio also needs to be held during Deep-sleep,
* `gpio_deep_sleep_hold_en` should also be called.
*
* Power down or call gpio_hold_dis will disable this function.
*
* @param gpio_num GPIO number, only support output-capable GPIOs
@ -555,7 +559,15 @@ esp_err_t gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t* stren
esp_err_t gpio_hold_en(gpio_num_t gpio_num);
/**
* @brief Unset gpio pad hold function.
* @brief Disable gpio pad hold function.
*
* When the chip is woken up from Deep-sleep, the gpio will be set to the default mode, so, the gpio will output
* the default level if this function is called. If you dont't want the level changes, the gpio should be configured to
* a known state before this function is called.
* e.g.
* If you hold gpio18 high during Deep-sleep, after the chip is woken up and `gpio_hold_dis` is called,
* gpio18 will output low level(because gpio18 is input mode by default). If you don't want this behavior,
* you should configure gpio18 as output mode and set it to hight level before calling `gpio_hold_dis`.
*
* @param gpio_num GPIO number, only support output-capable GPIOs
*
@ -563,7 +575,24 @@ esp_err_t gpio_hold_en(gpio_num_t gpio_num);
* - ESP_OK Success
* - ESP_ERR_NOT_SUPPORTED Not support pad hold function
*/
esp_err_t gpio_hold_dis(gpio_num_t gpio_num);
esp_err_t gpio_hold_dis(gpio_num_t gpio_num);
/**
* @brief Enable all digital gpio pad hold function during Deep-sleep.
*
* When the chip is in Deep-sleep mode, all digital gpio will hold the state before sleep, and when the chip is woken up,
* the status of digital gpio will not be held. Note that the pad hold feature only works when the chip is in Deep-sleep mode,
* when not in sleep mode, the digital gpio state can be changed even you have called this function.
*
* Power down or call gpio_hold_dis will disable this function, otherwise, the digital gpio hold feature works as long as the chip enter Deep-sleep.
*/
void gpio_deep_sleep_hold_en(void);
/**
* @brief Disable all digital gpio pad hold function during Deep-sleep.
*
*/
void gpio_deep_sleep_hold_dis(void);
/**
* @brief Set pad input to a peripheral signal through the IOMUX.

View File

@ -420,6 +420,35 @@ esp_err_t i2c_set_period(i2c_port_t i2c_num, int high_period, int low_period);
*/
esp_err_t i2c_get_period(i2c_port_t i2c_num, int* high_period, int* low_period);
/**
* @brief enable hardware filter on I2C bus
* Sometimes the I2C bus is disturbed by high frequency noise(about 20ns), or the rising edge of
* the SCL clock is very slow, these may cause the master state machine broken. enable hardware
* filter can filter out high frequency interference and make the master more stable.
* @note
* Enable filter will slow the SCL clock.
*
* @param i2c_num I2C port number
* @param cyc_num the APB cycles need to be filtered(0<= cyc_num <=7).
* When the period of a pulse is less than cyc_num * APB_cycle, the I2C controller will ignore this pulse.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t i2c_filter_enable(i2c_port_t i2c_num, uint8_t cyc_num);
/**
* @brief disable filter on I2C bus
*
* @param i2c_num I2C port number
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t i2c_filter_disable(i2c_port_t i2c_num);
/**
* @brief set I2C master start signal timing
*

View File

@ -139,6 +139,7 @@ typedef struct {
int dma_buf_count; /*!< I2S DMA Buffer Count */
int dma_buf_len; /*!< I2S DMA Buffer Length */
bool use_apll; /*!< I2S using APLL as main I2S clock, enable it to get accurate clock */
bool tx_desc_auto_clear; /*!< I2S auto clear tx descriptor if there is underflow condition (helps in avoiding noise in case of data unavailability) */
int fixed_mclk; /*!< I2S using fixed MCLK output. If use_apll = true and fixed_mclk > 0, then the clock output for i2s is fixed and equal to the fixed_mclk value.*/
} i2s_config_t;

View File

@ -135,16 +135,11 @@ typedef struct {
* This function may be called from an ISR, so, the code should be short and efficient.
*
* @param src Pointer to the buffer storing the raw data that needs to be converted to rmt format.
*
* @param[out] dest Pointer to the buffer storing the rmt format data.
*
* @param src_size The raw data size.
*
* @param wanted_num The number of rmt format data that wanted to get.
*
* @param[out] translated_size The size of the raw data that has been converted to rmt format,
* it should return 0 if no data is converted in user callback.
*
* @param[out] item_num The number of the rmt format data that actually converted to, it can be less than wanted_num if there is not enough raw data,
* but cannot exceed wanted_num. it should return 0 if no data was converted.
*
@ -159,7 +154,6 @@ typedef void (*sample_to_rmt_t)(const void* src, rmt_item32_t* dest, size_t src_
* @brief Set RMT clock divider, channel clock is divided from source clock.
*
* @param channel RMT channel (0-7)
*
* @param div_cnt RMT counter clock divider
*
* @return
@ -172,7 +166,6 @@ esp_err_t rmt_set_clk_div(rmt_channel_t channel, uint8_t div_cnt);
* @brief Get RMT clock divider, channel clock is divided from source clock.
*
* @param channel RMT channel (0-7)
*
* @param div_cnt pointer to accept RMT counter divider
*
* @return
@ -189,7 +182,6 @@ esp_err_t rmt_get_clk_div(rmt_channel_t channel, uint8_t* div_cnt);
* the receive process is finished.
*
* @param channel RMT channel (0-7)
*
* @param thresh RMT RX idle threshold
*
* @return
@ -206,7 +198,6 @@ esp_err_t rmt_set_rx_idle_thresh(rmt_channel_t channel, uint16_t thresh);
* the receive process is finished.
*
* @param channel RMT channel (0-7)
*
* @param thresh pointer to accept RMT RX idle threshold value
*
* @return
@ -234,7 +225,6 @@ esp_err_t rmt_get_rx_idle_thresh(rmt_channel_t channel, uint16_t *thresh);
* Channel 0 can use at most 8 blocks of memory, accordingly channel 7 can only use one memory block.
*
* @param channel RMT channel (0-7)
*
* @param rmt_mem_num RMT RX memory block number, one block has 64 * 32 bits.
*
* @return
@ -247,7 +237,6 @@ esp_err_t rmt_set_mem_block_num(rmt_channel_t channel, uint8_t rmt_mem_num);
* @brief Get RMT memory block number
*
* @param channel RMT channel (0-7)
*
* @param rmt_mem_num Pointer to accept RMT RX memory block number
*
* @return
@ -263,13 +252,9 @@ esp_err_t rmt_get_mem_block_num(rmt_channel_t channel, uint8_t* rmt_mem_num);
* The unit of carrier_high/low is the source clock tick, not the divided channel counter clock.
*
* @param channel RMT channel (0-7)
*
* @param carrier_en Whether to enable output carrier.
*
* @param high_level High level duration of carrier
*
* @param low_level Low level duration of carrier.
*
* @param carrier_level Configure the way carrier wave is modulated for channel 0-7.
* - 1'b1:transmit on low output level
* - 1'b0:transmit on high output level
@ -286,7 +271,6 @@ esp_err_t rmt_set_tx_carrier(rmt_channel_t channel, bool carrier_en, uint16_t hi
* Reduce power consumed by memory. 1:memory is in low power state.
*
* @param channel RMT channel (0-7)
*
* @param pd_en RMT memory low power enable.
*
* @return
@ -299,7 +283,6 @@ esp_err_t rmt_set_mem_pd(rmt_channel_t channel, bool pd_en);
* @brief Get RMT memory low power mode.
*
* @param channel RMT channel (0-7)
*
* @param pd_en Pointer to accept RMT memory low power mode.
*
* @return
@ -312,7 +295,6 @@ esp_err_t rmt_get_mem_pd(rmt_channel_t channel, bool* pd_en);
* @brief Set RMT start sending data from memory.
*
* @param channel RMT channel (0-7)
*
* @param tx_idx_rst Set true to reset memory index for TX.
* Otherwise, transmitter will continue sending from the last index in memory.
*
@ -337,7 +319,6 @@ esp_err_t rmt_tx_stop(rmt_channel_t channel);
* @brief Set RMT start receiving data.
*
* @param channel RMT channel (0-7)
*
* @param rx_idx_rst Set true to reset memory index for receiver.
* Otherwise, receiver will continue receiving data to the last index in memory.
*
@ -373,7 +354,6 @@ esp_err_t rmt_memory_rw_rst(rmt_channel_t channel);
* @brief Set RMT memory owner.
*
* @param channel RMT channel (0-7)
*
* @param owner To set when the transmitter or receiver can process the memory of channel.
*
* @return
@ -386,7 +366,6 @@ esp_err_t rmt_set_memory_owner(rmt_channel_t channel, rmt_mem_owner_t owner);
* @brief Get RMT memory owner.
*
* @param channel RMT channel (0-7)
*
* @param owner Pointer to get memory owner.
*
* @return
@ -399,7 +378,6 @@ esp_err_t rmt_get_memory_owner(rmt_channel_t channel, rmt_mem_owner_t* owner);
* @brief Set RMT tx loop mode.
*
* @param channel RMT channel (0-7)
*
* @param loop_en Enable RMT transmitter loop sending mode.
* If set true, transmitter will continue sending from the first data
* to the last data in channel 0-7 over and over again in a loop.
@ -414,7 +392,6 @@ esp_err_t rmt_set_tx_loop_mode(rmt_channel_t channel, bool loop_en);
* @brief Get RMT tx loop mode.
*
* @param channel RMT channel (0-7)
*
* @param loop_en Pointer to accept RMT transmitter loop sending mode.
*
* @return
@ -430,9 +407,7 @@ esp_err_t rmt_get_tx_loop_mode(rmt_channel_t channel, bool* loop_en);
* Counted in source clock, not divided counter clock.
*
* @param channel RMT channel (0-7)
*
* @param rx_filter_en To enable RMT receiver filter.
*
* @param thresh Threshold of pulse width for receiver.
*
* @return
@ -449,7 +424,6 @@ esp_err_t rmt_set_rx_filter(rmt_channel_t channel, bool rx_filter_en, uint8_t th
* 2. REF tick clock, which would be 1Mhz (not supported in this version).
*
* @param channel RMT channel (0-7)
*
* @param base_clk To choose source clock for RMT module.
*
* @return
@ -466,7 +440,6 @@ esp_err_t rmt_set_source_clk(rmt_channel_t channel, rmt_source_clk_t base_clk);
* 2. REF tick clock, which would be 1Mhz (not supported in this version).
*
* @param channel RMT channel (0-7)
*
* @param src_clk Pointer to accept source clock for RMT module.
*
* @return
@ -479,9 +452,7 @@ esp_err_t rmt_get_source_clk(rmt_channel_t channel, rmt_source_clk_t* src_clk);
* @brief Set RMT idle output level for transmitter
*
* @param channel RMT channel (0-7)
*
* @param idle_out_en To enable idle level output.
*
* @param level To set the output signal's level for channel 0-7 in idle state.
*
* @return
@ -490,11 +461,23 @@ esp_err_t rmt_get_source_clk(rmt_channel_t channel, rmt_source_clk_t* src_clk);
*/
esp_err_t rmt_set_idle_level(rmt_channel_t channel, bool idle_out_en, rmt_idle_level_t level);
/**
* @brief Get RMT idle output level for transmitter
*
* @param channel RMT channel (0-7)
* @param idle_out_en Pointer to accept value of enable idle.
* @param level Pointer to accept value of output signal's level in idle state for specified channel.
*
* @return
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_OK Success
*/
esp_err_t rmt_get_idle_level(rmt_channel_t channel, bool* idle_out_en, rmt_idle_level_t* level);
/**
* @brief Get RMT status
*
* @param channel RMT channel (0-7)
*
* @param status Pointer to accept channel status.
*
* @return
@ -523,7 +506,6 @@ void rmt_clr_intr_enable_mask(uint32_t mask);
* @brief Set RMT RX interrupt enable
*
* @param channel RMT channel (0 - 7)
*
* @param en enable or disable RX interrupt.
*
* @return
@ -536,7 +518,6 @@ esp_err_t rmt_set_rx_intr_en(rmt_channel_t channel, bool en);
* @brief Set RMT RX error interrupt enable
*
* @param channel RMT channel (0 - 7)
*
* @param en enable or disable RX err interrupt.
*
* @return
@ -549,7 +530,6 @@ esp_err_t rmt_set_err_intr_en(rmt_channel_t channel, bool en);
* @brief Set RMT TX interrupt enable
*
* @param channel RMT channel (0 - 7)
*
* @param en enable or disable TX interrupt.
*
* @return
@ -564,9 +544,7 @@ esp_err_t rmt_set_tx_intr_en(rmt_channel_t channel, bool en);
* An interrupt will be triggered when the number of transmitted items reaches the threshold value
*
* @param channel RMT channel (0 - 7)
*
* @param en enable or disable TX event interrupt.
*
* @param evt_thresh RMT event interrupt threshold value
*
* @return
@ -579,9 +557,7 @@ esp_err_t rmt_set_tx_thr_intr_en(rmt_channel_t channel, bool en, uint16_t evt_th
* @brief Set RMT pin
*
* @param channel RMT channel (0 - 7)
*
* @param mode TX or RX mode for RMT
*
* @param gpio_num GPIO number to transmit or receive the signal.
*
* @return
@ -637,11 +613,8 @@ esp_err_t rmt_isr_deregister(rmt_isr_handle_t handle);
* @brief Fill memory data of channel with given RMT items.
*
* @param channel RMT channel (0 - 7)
*
* @param item Pointer of items.
*
* @param item_num RMT sending items number.
*
* @param mem_offset Index offset of memory.
*
* @return
@ -654,9 +627,7 @@ esp_err_t rmt_fill_tx_items(rmt_channel_t channel, const rmt_item32_t* item, uin
* @brief Initialize RMT driver
*
* @param channel RMT channel (0 - 7)
*
* @param rx_buf_size Size of RMT RX ringbuffer. Can be 0 if the RX ringbuffer is not used.
*
* @param intr_alloc_flags Flags for the RMT driver interrupt handler. Pass 0 for default flags. See esp_intr_alloc.h for details.
* If ESP_INTR_FLAG_IRAM is used, please do not use the memory allocated from psram when calling rmt_write_items.
*
@ -685,12 +656,9 @@ esp_err_t rmt_driver_uninstall(rmt_channel_t channel);
* This API allows user to send waveform with any length.
*
* @param channel RMT channel (0 - 7)
*
* @param rmt_item head point of RMT items array.
* If ESP_INTR_FLAG_IRAM is used, please do not use the memory allocated from psram when calling rmt_write_items.
*
* @param item_num RMT data item number.
*
* @param wait_tx_done
* - If set 1, it will block the task and wait for sending done.
* - If set 0, it will not wait and return immediately.
@ -714,8 +682,7 @@ esp_err_t rmt_write_items(rmt_channel_t channel, const rmt_item32_t* rmt_item, i
* @brief Wait RMT TX finished.
*
* @param channel RMT channel (0 - 7)
*
* @param wait_time Maximum time in ticks to wait for transmission to be complete
* @param wait_time Maximum time in ticks to wait for transmission to be complete. If set 0, return immediately with ESP_ERR_TIMEOUT if TX is busy (polling).
*
* @return
* - ESP_OK RMT Tx done successfully
@ -731,7 +698,6 @@ esp_err_t rmt_wait_tx_done(rmt_channel_t channel, TickType_t wait_time);
* Users can get the RMT RX ringbuffer handle, and process the RX data.
*
* @param channel RMT channel (0 - 7)
*
* @param buf_handle Pointer to buffer handle to accept RX ringbuffer handle.
*
* @return
@ -746,7 +712,6 @@ esp_err_t rmt_get_ringbuf_handle(rmt_channel_t channel, RingbufHandle_t* buf_han
* If a channel is initialized more than once, tha user callback will be replaced by the later.
*
* @param channel RMT channel (0 - 7).
*
* @param fn Point to the data conversion function.
*
* @return
@ -760,11 +725,8 @@ esp_err_t rmt_translator_init(rmt_channel_t channel, sample_to_rmt_t fn);
* Requires rmt_translator_init to init the translator first.
*
* @param channel RMT channel (0 - 7).
*
* @param src Pointer to the raw data.
*
* @param src_size The size of the raw data.
*
* @param wait_tx_done Set true to wait all data send done.
*
* @return

View File

@ -87,6 +87,11 @@ typedef struct {
int quadhd_io_num; ///< GPIO pin for HD (HolD) signal which is used as D3 in 4-bit communication modes, or -1 if not used.
int max_transfer_sz; ///< Maximum transfer size, in bytes. Defaults to 4094 if 0.
uint32_t flags; ///< Abilities of bus to be checked by the driver. Or-ed value of ``SPICOMMON_BUSFLAG_*`` flags.
int intr_flags; /**< Interrupt flag for the bus to set the priority, and IRAM attribute, see
* ``esp_intr_alloc.h``. Note that the EDGE, INTRDISABLED attribute are ignored
* by the driver. Note that if ESP_INTR_FLAG_IRAM is set, ALL the callbacks of
* the driver, and their callee functions, should be put in the IRAM.
*/
} spi_bus_config_t;

View File

@ -79,8 +79,26 @@ typedef struct {
int spics_io_num; ///< CS GPIO pin for this device, or -1 if not used
uint32_t flags; ///< Bitwise OR of SPI_DEVICE_* flags
int queue_size; ///< Transaction queue size. This sets how many transactions can be 'in the air' (queued using spi_device_queue_trans but not yet finished using spi_device_get_trans_result) at the same time
transaction_cb_t pre_cb; ///< Callback to be called before a transmission is started. This callback is called within interrupt context.
transaction_cb_t post_cb; ///< Callback to be called after a transmission has completed. This callback is called within interrupt context.
transaction_cb_t pre_cb; /**< Callback to be called before a transmission is started.
*
* This callback is called within interrupt
* context should be in IRAM for best
* performance, see "Transferring Speed"
* section in the SPI Master documentation for
* full details. If not, the callback may crash
* during flash operation when the driver is
* initialized with ESP_INTR_FLAG_IRAM.
*/
transaction_cb_t post_cb; /**< Callback to be called after a transmission has completed.
*
* This callback is called within interrupt
* context should be in IRAM for best
* performance, see "Transferring Speed"
* section in the SPI Master documentation for
* full details. If not, the callback may crash
* during flash operation when the driver is
* initialized with ESP_INTR_FLAG_IRAM.
*/
} spi_device_interface_config_t;

View File

@ -44,8 +44,26 @@ typedef struct {
uint32_t flags; ///< Bitwise OR of SPI_SLAVE_* flags
int queue_size; ///< Transaction queue size. This sets how many transactions can be 'in the air' (queued using spi_slave_queue_trans but not yet finished using spi_slave_get_trans_result) at the same time
uint8_t mode; ///< SPI mode (0-3)
slave_transaction_cb_t post_setup_cb; ///< Callback called after the SPI registers are loaded with new data
slave_transaction_cb_t post_trans_cb; ///< Callback called after a transaction is done
slave_transaction_cb_t post_setup_cb; /**< Callback called after the SPI registers are loaded with new data.
*
* This callback is called within interrupt
* context should be in IRAM for best
* performance, see "Transferring Speed"
* section in the SPI Master documentation for
* full details. If not, the callback may crash
* during flash operation when the driver is
* initialized with ESP_INTR_FLAG_IRAM.
*/
slave_transaction_cb_t post_trans_cb; /**< Callback called after a transaction is done.
*
* This callback is called within interrupt
* context should be in IRAM for best
* performance, see "Transferring Speed"
* section in the SPI Master documentation for
* full details. If not, the callback may crash
* during flash operation when the driver is
* initialized with ESP_INTR_FLAG_IRAM.
*/
} spi_slave_interface_config_t;
/**

View File

@ -306,6 +306,14 @@ esp_err_t rmt_set_idle_level(rmt_channel_t channel, bool idle_out_en, rmt_idle_l
return ESP_OK;
}
esp_err_t rmt_get_idle_level(rmt_channel_t channel, bool* idle_out_en, rmt_idle_level_t* level)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
*idle_out_en = (bool) (RMT.conf_ch[channel].conf1.idle_out_en);
*level = (rmt_idle_level_t) (RMT.conf_ch[channel].conf1.idle_out_lv);
return ESP_OK;
}
esp_err_t rmt_get_status(rmt_channel_t channel, uint32_t* status)
{
RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
@ -837,7 +845,9 @@ esp_err_t rmt_wait_tx_done(rmt_channel_t channel, TickType_t wait_time)
return ESP_OK;
}
else {
ESP_LOGE(RMT_TAG, "Timeout on wait_tx_done");
if (wait_time != 0) { // Don't emit error message if just polling.
ESP_LOGE(RMT_TAG, "Timeout on wait_tx_done");
}
return ESP_ERR_TIMEOUT;
}
}

View File

@ -233,6 +233,10 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK( dma_chan >= 0 && dma_chan <= 2, "invalid dma channel", ESP_ERR_INVALID_ARG );
SPI_CHECK((bus_config->intr_flags & (ESP_INTR_FLAG_HIGH|ESP_INTR_FLAG_EDGE|ESP_INTR_FLAG_INTRDISABLED))==0, "intr flag not allowed", ESP_ERR_INVALID_ARG);
#ifndef CONFIG_SPI_MASTER_ISR_IN_IRAM
SPI_CHECK((bus_config->intr_flags & ESP_INTR_FLAG_IRAM)==0, "ESP_INTR_FLAG_IRAM should be disabled when CONFIG_SPI_MASTER_ISR_IN_IRAM is not set.", ESP_ERR_INVALID_ARG);
#endif
spi_chan_claimed=spicommon_periph_claim(host);
SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
@ -284,10 +288,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
}
}
int flags = ESP_INTR_FLAG_INTRDISABLED;
#ifdef CONFIG_SPI_MASTER_ISR_IN_IRAM
flags |= ESP_INTR_FLAG_IRAM;
#endif
int flags = bus_config->intr_flags | ESP_INTR_FLAG_INTRDISABLED;
err = esp_intr_alloc(spicommon_irqsource_for_host(host), flags, spi_intr, (void*)spihost[host], &spihost[host]->intr);
if (err != ESP_OK) {
ret = err;

View File

@ -109,6 +109,10 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
//We only support HSPI/VSPI, period.
SPI_CHECK(VALID_HOST(host), "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK( dma_chan >= 0 && dma_chan <= 2, "invalid dma channel", ESP_ERR_INVALID_ARG );
SPI_CHECK((bus_config->intr_flags & (ESP_INTR_FLAG_HIGH|ESP_INTR_FLAG_EDGE|ESP_INTR_FLAG_INTRDISABLED))==0, "intr flag not allowed", ESP_ERR_INVALID_ARG);
#ifndef CONFIG_SPI_SLAVE_ISR_IN_IRAM
SPI_CHECK((bus_config->intr_flags & ESP_INTR_FLAG_IRAM)==0, "ESP_INTR_FLAG_IRAM should be disabled when CONFIG_SPI_SLAVE_ISR_IN_IRAM is not set.", ESP_ERR_INVALID_ARG);
#endif
spi_chan_claimed=spicommon_periph_claim(host);
SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
@ -174,10 +178,7 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
goto cleanup;
}
int flags = ESP_INTR_FLAG_INTRDISABLED;
#ifdef CONFIG_SPI_SLAVE_ISR_IN_IRAM
flags |= ESP_INTR_FLAG_IRAM;
#endif
int flags = bus_config->intr_flags | ESP_INTR_FLAG_INTRDISABLED;
err = esp_intr_alloc(spicommon_irqsource_for_host(host), flags, spi_intr, (void *)spihost[host], &spihost[host]->intr);
if (err != ESP_OK) {
ret = err;

View File

@ -875,6 +875,7 @@ static void uart_rx_intr_handler_default(void *param)
//If we fail to push data to ring buffer, we will have to stash the data, and send next time.
//Mainly for applications that uses flow control or small ring buffer.
if(pdFALSE == xRingbufferSendFromISR(p_uart->rx_ring_buf, p_uart->rx_data_buf, p_uart->rx_stash_len, &HPTaskAwoken)) {
p_uart->rx_buffer_full_flg = true;
uart_disable_intr_mask(uart_num, UART_RXFIFO_TOUT_INT_ENA_M | UART_RXFIFO_FULL_INT_ENA_M);
if (uart_event.type == UART_PATTERN_DET) {
if (rx_fifo_len < pat_num) {
@ -893,7 +894,6 @@ static void uart_rx_intr_handler_default(void *param)
}
}
uart_event.type = UART_BUFFER_FULL;
p_uart->rx_buffer_full_flg = true;
} else {
UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
if (uart_intr_status & UART_AT_CMD_CHAR_DET_INT_ST_M) {
@ -1164,6 +1164,22 @@ int uart_write_bytes_with_break(uart_port_t uart_num, const char* src, size_t si
return uart_tx_all(uart_num, src, size, 1, brk_len);
}
static bool uart_check_buf_full(uart_port_t uart_num)
{
if(p_uart_obj[uart_num]->rx_buffer_full_flg) {
BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1);
if(res == pdTRUE) {
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len;
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);
return true;
}
}
return false;
}
int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait)
{
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1));
@ -1184,8 +1200,17 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp
p_uart_obj[uart_num]->rx_ptr = data;
p_uart_obj[uart_num]->rx_cur_remain = size;
} else {
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
return copy_len;
//When using dual cores, `rx_buffer_full_flg` may read and write on different cores at same time,
//which may lose synchronization. So we also need to call `uart_check_buf_full` once when ringbuffer is empty
//to solve the possible asynchronous issues.
if(uart_check_buf_full(uart_num)) {
//This condition will never be true if `uart_read_bytes`
//and `uart_rx_intr_handler_default` are scheduled on the same core.
continue;
} else {
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
return copy_len;
}
}
}
if(p_uart_obj[uart_num]->rx_cur_remain > length) {
@ -1206,16 +1231,7 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp
vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_head_ptr);
p_uart_obj[uart_num]->rx_head_ptr = NULL;
p_uart_obj[uart_num]->rx_ptr = NULL;
if(p_uart_obj[uart_num]->rx_buffer_full_flg) {
BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1);
if(res == pdTRUE) {
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len;
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);
}
}
uart_check_buf_full(uart_num);
}
}

View File

@ -91,7 +91,10 @@ else()
)
if(CONFIG_SPIRAM_CACHE_WORKAROUND)
add_compile_options(-mfix-esp32-psram-cache-issue)
# Note: Adding as a PUBLIC compile option here causes this option to propagate to all components that depend on esp32.
#
# To handle some corner cases, the same flag is set in project_include.cmake
target_compile_options(esp32 PUBLIC -mfix-esp32-psram-cache-issue)
else()
target_linker_script(esp32 "ld/esp32.rom.spiram_incompatible_fns.ld")
endif()
@ -148,4 +151,10 @@ else()
if(NOT "${BUILD_TEST_COMPONENTS}" EQUAL "")
add_definitions(-DESP_TIMER_DYNAMIC_OVERFLOW_VAL)
endif()
# disable stack protection in files which are involved in initialization of that feature
set_source_files_properties(
stack_check.c cpu_start.c
PROPERTIES COMPILE_FLAGS
-fno-stack-protector)
endif()

View File

@ -124,7 +124,8 @@ config SPIRAM_CACHE_WORKAROUND
help
Revision 1 of the ESP32 has a bug that can cause a write to PSRAM not to take place in some situations
when the cache line needs to be fetched from external RAM and an interrupt occurs. This enables a
fix in the compiler that makes sure the specific code that is vulnerable to this will not be emitted.
fix in the compiler (-mfix-esp32-psram-cache-issue) that makes sure the specific code that is vulnerable
to this will not be emitted.
This will also not use any bits of newlib that are located in ROM, opting for a version that is compiled
with the workaround and located in flash instead.
@ -213,6 +214,29 @@ config SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
in PSRAM instead of internal memory, and placed most of variables of lwip,net802.11,pp,bluedroid library
to external memory defaultly.
choice SPIRAM_OCCUPY_SPI_HOST
prompt "SPI host to use for 32MBit PSRAM"
default SPIRAM_OCCUPY_VSPI_HOST
depends on SPIRAM_SPEED_80M
help
When both flash and PSRAM is working under 80MHz, and the PSRAM is of type 32MBit, one of the HSPI/VSPI
host will be used to output the clock. Select which one to use here.
config SPIRAM_OCCUPY_HSPI_HOST
bool "HSPI host (SPI2)"
config SPIRAM_OCCUPY_VSPI_HOST
bool "VSPI host (SPI3)"
endchoice
config PICO_PSRAM_CS_IO
int "PSRAM CS IO for ESP32-PICO chip"
depends on SPIRAM_SUPPORT
range 0 33
default 10
help
When ESP32-PICO chip connect a external psram, the clock IO and data IO is fixed, but the CS IO can be
any unused GPIO, user can config it based on hardware design.
endmenu
config MEMMAP_TRACEMEM

View File

@ -124,6 +124,7 @@ void IRAM_ATTR call_start_cpu0()
RESET_REASON rst_reas[2];
#endif
cpu_configure_region_protection();
cpu_init_memctl();
//Move exception vectors to IRAM
asm volatile (\
@ -249,6 +250,7 @@ void IRAM_ATTR call_start_cpu1()
ets_set_appcpu_boot_addr(0);
cpu_configure_region_protection();
cpu_init_memctl();
#if CONFIG_CONSOLE_UART_NONE
ets_install_putc1(NULL);

View File

@ -83,10 +83,13 @@ static esp_timer_handle_t s_timer_in_callback;
static TaskHandle_t s_timer_task;
// counting semaphore used to notify the timer task from ISR
static SemaphoreHandle_t s_timer_semaphore;
// mutex which protects timers from deletion during callback execution
static SemaphoreHandle_t s_timer_delete_mutex;
#if CONFIG_SPIRAM_USE_MALLOC
// memory for s_timer_semaphore
// memory for s_timer_semaphore and s_timer_delete_mutex
static StaticQueue_t s_timer_semaphore_memory;
static StaticQueue_t s_timer_delete_mutex_memory;
#endif
// lock protecting s_timers, s_inactive_timers, s_timer_in_callback
@ -154,19 +157,21 @@ esp_err_t IRAM_ATTR esp_timer_stop(esp_timer_handle_t timer)
esp_err_t esp_timer_delete(esp_timer_handle_t timer)
{
if (timer == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (timer_armed(timer)) {
return ESP_ERR_INVALID_STATE;
}
xSemaphoreTakeRecursive(s_timer_delete_mutex, portMAX_DELAY);
#if WITH_PROFILING
if (timer == s_timer_in_callback) {
s_timer_in_callback = NULL;
}
timer_remove_inactive(timer);
#endif
if (timer == NULL) {
return ESP_ERR_INVALID_ARG;
}
free(timer);
xSemaphoreGiveRecursive(s_timer_delete_mutex);
return ESP_OK;
}
@ -261,6 +266,7 @@ static void timer_process_alarm(esp_timer_dispatch_t dispatch_method)
/* unused, provision to allow running callbacks from ISR */
(void) dispatch_method;
xSemaphoreTakeRecursive(s_timer_delete_mutex, portMAX_DELAY);
timer_list_lock();
uint64_t now = esp_timer_impl_get_time();
esp_timer_handle_t it = LIST_FIRST(&s_timers);
@ -301,6 +307,7 @@ static void timer_process_alarm(esp_timer_dispatch_t dispatch_method)
esp_timer_impl_set_alarm(first->alarm);
}
timer_list_unlock();
xSemaphoreGiveRecursive(s_timer_delete_mutex);
}
static void timer_task(void* arg)
@ -332,6 +339,7 @@ static IRAM_ATTR bool is_initialized()
esp_err_t esp_timer_init(void)
{
esp_err_t err;
if (is_initialized()) {
return ESP_ERR_INVALID_STATE;
}
@ -343,27 +351,50 @@ esp_err_t esp_timer_init(void)
s_timer_semaphore = xSemaphoreCreateCounting(TIMER_EVENT_QUEUE_SIZE, 0);
#endif
if (!s_timer_semaphore) {
return ESP_ERR_NO_MEM;
err = ESP_ERR_NO_MEM;
goto out;
}
#if CONFIG_SPIRAM_USE_MALLOC
memset(&s_timer_delete_mutex_memory, 0, sizeof(StaticQueue_t));
s_timer_delete_mutex = xSemaphoreCreateRecursiveMutexStatic(&s_timer_delete_mutex_memory);
#else
s_timer_delete_mutex = xSemaphoreCreateRecursiveMutex();
#endif
if (!s_timer_delete_mutex) {
err = ESP_ERR_NO_MEM;
goto out;
}
int ret = xTaskCreatePinnedToCore(&timer_task, "esp_timer",
ESP_TASK_TIMER_STACK, NULL, ESP_TASK_TIMER_PRIO, &s_timer_task, PRO_CPU_NUM);
if (ret != pdPASS) {
vSemaphoreDelete(s_timer_semaphore);
s_timer_semaphore = NULL;
return ESP_ERR_NO_MEM;
err = ESP_ERR_NO_MEM;
goto out;
}
esp_err_t err = esp_timer_impl_init(&timer_alarm_handler);
err = esp_timer_impl_init(&timer_alarm_handler);
if (err != ESP_OK) {
vTaskDelete(s_timer_task);
s_timer_task = NULL;
vSemaphoreDelete(s_timer_semaphore);
s_timer_semaphore = NULL;
return err;
goto out;
}
return ESP_OK;
out:
if (s_timer_task) {
vTaskDelete(s_timer_task);
s_timer_task = NULL;
}
if (s_timer_semaphore) {
vSemaphoreDelete(s_timer_semaphore);
s_timer_semaphore = NULL;
}
if (s_timer_delete_mutex) {
vSemaphoreDelete(s_timer_delete_mutex);
s_timer_delete_mutex = NULL;
}
return ESP_ERR_NO_MEM;
}
esp_err_t esp_timer_deinit(void)

View File

@ -97,7 +97,7 @@ static uint32_t s_alarm_overflow_val = DEFAULT_ALARM_OVERFLOW_VAL;
static const char* TAG = "esp_timer_impl";
// Interrupt handle retuned by the interrupt allocator
// Interrupt handle returned by the interrupt allocator
static intr_handle_t s_timer_interrupt_handle;
// Function from the upper layer to be called when the interrupt happens.
@ -123,7 +123,7 @@ static uint32_t s_timer_us_per_overflow;
// value than the one which caused an interrupt. This can cause interrupt handler
// to consider that the interrupt has happened due to timer overflow, incrementing
// s_time_base_us. To avoid this, frequency switch hook sets this flag if
// it needs to set timer alarm value to ALARM_OVERFLOW_VAL. Interrupt hanler
// it needs to set timer alarm value to ALARM_OVERFLOW_VAL. Interrupt handler
// will not increment s_time_base_us if this flag is set.
static bool s_mask_overflow;

View File

@ -27,10 +27,12 @@
#include <string.h>
#include <stdio.h>
#include <sys/lock.h>
#include <byteswap.h>
#include <assert.h>
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "hwcrypto/sha.h"
#include "rom/ets_sys.h"
#include "soc/dport_reg.h"
@ -53,25 +55,30 @@ inline static uint32_t SHA_CONTINUE_REG(esp_sha_type sha_type) {
return SHA_1_CONTINUE_REG + sha_type * 0x10;
}
/* Single lock for SHA engine memory block
/* Single spinlock for SHA engine memory block
*/
static _lock_t memory_block_lock;
static portMUX_TYPE memory_block_lock = portMUX_INITIALIZER_UNLOCKED;
typedef struct {
_lock_t lock;
bool in_use;
} sha_engine_state;
/* Pointer to state of each concurrent SHA engine.
/* Binary semaphore managing the state of each concurrent SHA engine.
Available = noone is using this SHA engine
Taken = a SHA session is running on this SHA engine
Indexes:
0 = SHA1
1 = SHA2_256
2 = SHA2_384 or SHA2_512
*/
static sha_engine_state engine_states[3];
static SemaphoreHandle_t engine_states[3];
/* Index into the sha_engine_state array */
static uint8_t engines_in_use;
/* Spinlock for engines_in_use counter
*/
static portMUX_TYPE engines_in_use_lock = portMUX_INITIALIZER_UNLOCKED;
/* Index into the engine_states array */
inline static size_t sha_engine_index(esp_sha_type type) {
switch(type) {
case SHA1:
@ -115,82 +122,97 @@ inline static size_t block_length(esp_sha_type type) {
void esp_sha_lock_memory_block(void)
{
_lock_acquire(&memory_block_lock);
portENTER_CRITICAL(&memory_block_lock);
}
void esp_sha_unlock_memory_block(void)
{
_lock_release(&memory_block_lock);
portEXIT_CRITICAL(&memory_block_lock);
}
/* Lock to hold when changing SHA engine state,
allows checking of sha_engines_all_idle()
*/
static _lock_t state_change_lock;
static SemaphoreHandle_t sha_get_engine_state(esp_sha_type sha_type)
{
unsigned idx = sha_engine_index(sha_type);
volatile SemaphoreHandle_t *engine = &engine_states[idx];
SemaphoreHandle_t result = *engine;
inline static bool sha_engines_all_idle() {
return !engine_states[0].in_use
&& !engine_states[1].in_use
&& !engine_states[2].in_use;
if (result == NULL) {
// Create a new semaphore for 'in use' flag
SemaphoreHandle_t new_engine = xSemaphoreCreateBinary();
assert(new_engine != NULL);
xSemaphoreGive(new_engine); // start available
// try to atomically set the previously NULL *engine to new_engine
uint32_t set_engine = (uint32_t)new_engine;
uxPortCompareSet((volatile uint32_t *)engine, 0, &set_engine);
if (set_engine != 0) { // we lost a race setting *engine
vSemaphoreDelete(new_engine);
}
result = *engine;
}
return result;
}
static void esp_sha_lock_engine_inner(sha_engine_state *engine);
static bool esp_sha_lock_engine_common(esp_sha_type sha_type, TickType_t ticks_to_wait);
bool esp_sha_try_lock_engine(esp_sha_type sha_type)
{
sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
if(_lock_try_acquire(&engine->lock) != 0) {
/* This SHA engine is already in use */
return false;
} else {
esp_sha_lock_engine_inner(engine);
return true;
}
return esp_sha_lock_engine_common(sha_type, 0);
}
void esp_sha_lock_engine(esp_sha_type sha_type)
{
sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
_lock_acquire(&engine->lock);
esp_sha_lock_engine_inner(engine);
esp_sha_lock_engine_common(sha_type, portMAX_DELAY);
}
static void esp_sha_lock_engine_inner(sha_engine_state *engine)
static bool esp_sha_lock_engine_common(esp_sha_type sha_type, TickType_t ticks_to_wait)
{
_lock_acquire(&state_change_lock);
SemaphoreHandle_t engine_state = sha_get_engine_state(sha_type);
BaseType_t result = xSemaphoreTake(engine_state, ticks_to_wait);
if (sha_engines_all_idle()) {
/* Enable SHA hardware */
if (result == pdFALSE) {
// failed to take semaphore
return false;
}
portENTER_CRITICAL(&engines_in_use_lock);
if (engines_in_use == 0) {
/* Just locked first engine,
so enable SHA hardware */
periph_module_enable(PERIPH_SHA_MODULE);
DPORT_STALL_OTHER_CPU_START();
ets_sha_enable();
DPORT_STALL_OTHER_CPU_END();
}
assert( !engine->in_use && "in_use flag should be cleared" );
engine->in_use = true;
engines_in_use++;
assert(engines_in_use <= 3);
_lock_release(&state_change_lock);
portEXIT_CRITICAL(&engines_in_use_lock);
return true;
}
void esp_sha_unlock_engine(esp_sha_type sha_type)
{
sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
SemaphoreHandle_t *engine_state = sha_get_engine_state(sha_type);
_lock_acquire(&state_change_lock);
portENTER_CRITICAL(&engines_in_use_lock);
assert( engine->in_use && "in_use flag should be set" );
engine->in_use = false;
engines_in_use--;
if (sha_engines_all_idle()) {
/* Disable SHA hardware */
if (engines_in_use == 0) {
/* About to release last engine, so
disable SHA hardware */
periph_module_disable(PERIPH_SHA_MODULE);
}
_lock_release(&state_change_lock);
portEXIT_CRITICAL(&engines_in_use_lock);
_lock_release(&engine->lock);
xSemaphoreGive(engine_state);
}
void esp_sha_wait_idle(void)
@ -207,8 +229,16 @@ void esp_sha_wait_idle(void)
void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
{
sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
assert(engine->in_use && "SHA engine should be locked" );
#ifndef NDEBUG
{
SemaphoreHandle_t *engine_state = sha_get_engine_state(sha_type);
assert(uxSemaphoreGetCount(engine_state) == 0 &&
"SHA engine should be locked" );
}
#endif
// preemptively do this before entering the critical section, then re-check once in it
esp_sha_wait_idle();
esp_sha_lock_memory_block();
@ -234,8 +264,16 @@ void esp_sha_read_digest_state(esp_sha_type sha_type, void *digest_state)
void esp_sha_block(esp_sha_type sha_type, const void *data_block, bool is_first_block)
{
sha_engine_state *engine = &engine_states[sha_engine_index(sha_type)];
assert(engine->in_use && "SHA engine should be locked" );
#ifndef NDEBUG
{
SemaphoreHandle_t *engine_state = sha_get_engine_state(sha_type);
assert(uxSemaphoreGetCount(engine_state) == 0 &&
"SHA engine should be locked" );
}
#endif
// preemptively do this before entering the critical section, then re-check once in it
esp_sha_wait_idle();
esp_sha_lock_memory_block();

View File

@ -185,6 +185,13 @@ typedef enum {
Fixed Root Setting of each device is variable as that setting changes of the root. */
MESH_EVENT_SCAN_DONE, /**< if self-organized networking is disabled, user can call esp_wifi_scan_start() to trigger
this event, and add the corresponding scan done handler in this event. */
MESH_EVENT_NETWORK_STATE, /**< network state, such as whether current mesh network has a root. */
MESH_EVENT_STOP_RECONNECTION, /**< the root stops reconnecting to the router and non-root devices stop reconnecting to their parents. */
MESH_EVENT_FIND_NETWORK, /**< when the channel field in mesh configuration is set to zero, mesh stack will perform a
full channel scan to find a mesh network that can join, and return the channel value
after finding it. */
MESH_EVENT_ROUTER_SWITCH, /**< if users specify BSSID of the router in mesh configuration, when the root connects to another
router with the same SSID, this event will be posted and the new router information is attached. */
MESH_EVENT_MAX,
} mesh_event_id_t;
@ -229,13 +236,18 @@ typedef enum {
* @brief Mesh disconnect reason code
*/
typedef enum {
MESH_REASON_CYCLIC = 100, /**< cyclic is detected */
MESH_REASON_PARENT_IDLE, /**< parent is idle */
MESH_REASON_LEAF, /**< the connected device is changed to a leaf */
MESH_REASON_DIFF_ID, /**< in different mesh ID */
MESH_REASON_ROOTS, /**< root conflict is detected */
MESH_REASON_PARENT_STOPPED, /**< parent has stopped the mesh */
MESH_REASON_SCAN_FAIL, /**< scan fail */
MESH_REASON_CYCLIC = 100, /**< cyclic is detected */
MESH_REASON_PARENT_IDLE, /**< parent is idle */
MESH_REASON_LEAF, /**< the connected device is changed to a leaf */
MESH_REASON_DIFF_ID, /**< in different mesh ID */
MESH_REASON_ROOTS, /**< root conflict is detected */
MESH_REASON_PARENT_STOPPED, /**< parent has stopped the mesh */
MESH_REASON_SCAN_FAIL, /**< scan fail */
MESH_REASON_IE_UNKNOWN, /**< unknown IE */
MESH_REASON_WAIVE_ROOT, /**< waive root */
MESH_REASON_PARENT_WORSE, /**< parent with very poor RSSI */
MESH_REASON_EMPTY_PASSWORD, /**< use an empty password to connect to an encrypted parent */
MESH_REASON_PARENT_UNENCRYPTED, /**< connect to an unencrypted parent/router */
} mesh_disconnect_reason_t;
/*******************************************************
@ -303,6 +315,14 @@ typedef struct {
mesh_addr_t rc_addr; /**< root address specified by users via API esp_mesh_waive_root() */
} mesh_event_vote_started_t;
/**
* @brief find a mesh network that this device can join
*/
typedef struct {
uint8_t channel; /**< channel number of the new found network */
uint8_t router_bssid[6]; /**< router BSSID */
} mesh_event_find_network_t;
/**
* @brief IP settings from LwIP stack
*/
@ -367,6 +387,18 @@ typedef struct {
uint8_t number; /**< the number of APs scanned */
} mesh_event_scan_done_t;
/**
* @brief Network state information
*/
typedef struct {
bool is_rootless; /**< whether current mesh network has a root */
} mesh_event_network_state_t;
/**
* @brief New router information
*/
typedef system_event_sta_connected_t mesh_event_router_switch_t;
/**
* @brief Mesh event information
*/
@ -390,6 +422,9 @@ typedef union {
mesh_event_root_conflict_t root_conflict; /**< other powerful root */
mesh_event_root_fixed_t root_fixed; /**< fixed root */
mesh_event_scan_done_t scan_done; /**< scan done */
mesh_event_network_state_t network_state; /**< network state, such as whether current mesh network has a root. */
mesh_event_find_network_t find_network; /**< network found that can join */
mesh_event_router_switch_t router_switch; /**< new router information */
} mesh_event_info_t;
/**
@ -430,10 +465,16 @@ typedef struct {
* @brief Router configuration
*/
typedef struct {
uint8_t ssid[32]; /**< SSID */
uint8_t ssid_len; /**< length of SSID */
uint8_t bssid[6]; /**< BSSID, if router is hidden, this value is mandatory */
uint8_t password[64]; /**< password */
uint8_t ssid[32]; /**< SSID */
uint8_t ssid_len; /**< length of SSID */
uint8_t bssid[6]; /**< BSSID, if this value is specified, users should also specify "allow_router_switch". */
uint8_t password[64]; /**< password */
bool allow_router_switch; /**< if the BSSID is specified and this value is also set, when the router of this specified BSSID
fails to be found after "fail" (mesh_attempts_t) times, the whole network is allowed to switch
to another router with the same SSID. The new router might also be on a different channel.
The default value is false.
There is a risk that if the password is different between the new switched router and the previous
one, the mesh network could be established but the root will never connect to the new switched router. */
} mesh_router_t;
/**
@ -449,6 +490,8 @@ typedef struct {
*/
typedef struct {
uint8_t channel; /**< channel, the mesh network on */
bool allow_channel_switch; /**< if this value is set, when "fail" (mesh_attempts_t) times is reached, device will change to
a full channel scan for a network that could join. The default value is false. */
mesh_event_cb_t event_cb; /**< mesh event callback */
mesh_addr_t mesh_id; /**< mesh network identification */
mesh_router_t router; /**< router configuration */
@ -581,6 +624,7 @@ esp_err_t esp_mesh_stop(void);
* - If the packet is to an external IP network, set this parameter to the IPv4:PORT combination.
* This packet will be delivered to the root firstly, then the root will forward this packet to the final IP server address.
* @param[in] data pointer to a sending mesh packet
* - Field size should not exceed MESH_MPS. Note that the size of one mesh packet should not exceed MESH_MTU.
* - Field proto should be set to data protocol in use (default is MESH_PROTO_BIN for binary).
* - Field tos should be set to transmission tos (type of service) in use (default is MESH_TOS_P2P for point-to-point reliable).
* @param[in] flag bitmap for data sent
@ -927,9 +971,9 @@ bool esp_mesh_is_root(void);
* @attention This API is used to dynamically modify whether to enable the self organizing.
*
* @param[in] enable enable or disable self-organized networking
* @param[in] select_parent
* - If self-organized networking is enabled, let the device search for a new parent or
* keep connecting to the previous parent.
* @param[in] select_parent Only valid when self-organized networking is enabled.
* - if select_parent is set to true, the root will give up its mesh root status and search for a new parent
* like other non-root devices.
*
* @return
* - ESP_OK
@ -1000,9 +1044,10 @@ esp_err_t esp_mesh_set_vote_percentage(float percentage);
float esp_mesh_get_vote_percentage(void);
/**
* @brief Set mesh softAP associate expired time
* @brief Set mesh softAP associate expired time (default:10 seconds)
* - If mesh softAP hasn't received any data from an associated child within this time,
* mesh softAP will take this child inactive and disassociate it.
* - If mesh softAP is encrypted, this value should be set a greater value, such as 30 seconds.
*
* @param[in] seconds the expired time
*
@ -1183,7 +1228,7 @@ esp_err_t esp_mesh_get_group_list(mesh_addr_t *addr, int num);
bool esp_mesh_is_my_group(const mesh_addr_t *addr);
/**
* @brief Set mesh network capacity
* @brief Set mesh network capacity (max:1000, default:300)
*
* @attention This API shall be called before mesh is started.
*
@ -1381,6 +1426,59 @@ esp_err_t esp_mesh_get_subnet_nodes_num(const mesh_addr_t *child_mac, int *nodes
*/
esp_err_t esp_mesh_get_subnet_nodes_list(const mesh_addr_t *child_mac, mesh_addr_t *nodes, int nodes_num);
/**
* @brief Disconnect from current parent
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_disconnect(void);
/**
* @brief Connect to current parent
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_connect(void);
/**
* @brief Flush scan result
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_flush_scan_result(void);
/**
* @brief Cause the root device to add Channel Switch Announcement Element (CSA IE) to beacon
* - Set the new channel
* - Set how many beacons with CSA IE will be sent before changing a new channel
* - Enable the channel switch function
*
* @attention This API is only called by the root.
*
* @param[in] new_bssid the new router BSSID if the router changes
* @param[in] csa_newchan the new channel number to which the whole network is moving
* @param[in] csa_count channel switch period(beacon count), unit is based on beacon interval of its softAP, the default value is 15.
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_switch_channel(const uint8_t *new_bssid, int csa_newchan, int csa_count);
/**
* @brief Get the router BSSID
*
* @param[out] router_bssid pointer to the router BSSID
*
* @return
* - ESP_OK
* - ESP_ERR_WIFI_NOT_INIT
* - ESP_ERR_WIFI_ARG
*/
esp_err_t esp_mesh_get_router_bssid(uint8_t *router_bssid);
#ifdef __cplusplus
}
#endif

View File

@ -214,6 +214,12 @@ esp_err_t esp_modem_sleep_register(modem_sleep_module_t module);
*/
esp_err_t esp_modem_sleep_deregister(modem_sleep_module_t module);
/**
* @brief Get the time stamp when PHY/RF was switched on
* @return return 0 if PHY/RF is never switched on. Otherwise return time in
* microsecond since boot when phy/rf was last switched on
*/
int64_t esp_phy_rf_get_on_ts(void);
#ifdef __cplusplus
}
#endif

View File

@ -22,8 +22,9 @@
#include "esp_err.h"
typedef enum {
ESP_SPIRAM_SIZE_32MBITS = 0, /*!< SPI RAM size is 32 MBits */
ESP_SPIRAM_SIZE_64MBITS = 1, /*!< SPI RAM size is 64 MBits */
ESP_SPIRAM_SIZE_16MBITS = 0, /*!< SPI RAM size is 16 MBits */
ESP_SPIRAM_SIZE_32MBITS = 1, /*!< SPI RAM size is 32 MBits */
ESP_SPIRAM_SIZE_64MBITS = 2, /*!< SPI RAM size is 64 MBits */
ESP_SPIRAM_SIZE_INVALID, /*!< SPI RAM size is invalid */
} esp_spiram_size_t;
@ -56,7 +57,7 @@ void esp_spiram_init_cache();
/**
* @brief Memory test for SPI RAM. Should be called after SPI RAM is initialized and
* (in case of a dual-core system) the app CPU is online. This test overwrites the
* (in case of a dual-core system) the app CPU is online. This test overwrites the
* memory with crap, so do not call after e.g. the heap allocator has stored important
* stuff in SPI RAM.
*
@ -102,4 +103,14 @@ void esp_spiram_writeback_cache();
esp_err_t esp_spiram_reserve_dma_pool(size_t size);
/**
* @brief If SPI RAM(PSRAM) has been initialized
*
* @return
* - true SPI RAM has been initialized successfully
* - false SPI RAM hasn't been initialized or initialized failed
*/
bool esp_spiram_is_initialized(void);
#endif

View File

@ -405,7 +405,7 @@ typedef struct {
typedef struct {
wifi_pkt_rx_ctrl_t rx_ctrl;/**< received packet radio metadata header of the CSI data */
uint8_t mac[6]; /**< source MAC address of the CSI data */
bool last_word_invalid; /**< last four bytes of the CSI data is invalid or not */
bool first_word_invalid; /**< first four bytes of the CSI data is invalid or not */
int8_t *buf; /**< buffer of CSI data */
uint16_t len; /**< length of CSI data */
} wifi_csi_info_t;

View File

@ -166,6 +166,8 @@ void esp_sha_unlock_engine(esp_sha_type sha_type);
* while it is in use by the SHA engine. Caller should use esp_sha_wait_idle()
* to ensure the SHA engine is not reading from the memory block in hardware.
*
* @note This function enters a critical section. Do not block while holding this lock.
*
* @note You do not need to lock the memory block before calling esp_sha_block() or esp_sha_read_digest_state(), these functions handle memory block locking internally.
*
* Call esp_sha_unlock_memory_block() when done.
@ -177,6 +179,8 @@ void esp_sha_lock_memory_block(void);
*
* Caller should have already locked a SHA engine before calling this function.
*
* This function releases the critical section entered by esp_sha_lock_memory_block().
*
* Call following esp_sha_lock_memory_block().
*/
void esp_sha_unlock_memory_block(void);

View File

@ -1401,5 +1401,16 @@ extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP7_IDENT);
#define XCHAL_ERRATUM_497 0
#endif
/*
* Erratum 572 (releases TBD, but present in ESP32)
* Disable zero-overhead loop buffer to prevent rare illegal instruction
* exceptions while executing zero-overhead loops.
*/
#if ( XCHAL_HAVE_LOOPS && XCHAL_LOOP_BUFFER_SIZE != 0 )
#define XCHAL_ERRATUM_572 1
#else
#define XCHAL_ERRATUM_572 0
#endif
#endif /*XTENSA_CONFIG_CORE_H*/

View File

@ -12,6 +12,7 @@ SECTIONS
*libpp.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
*liblwip.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
*libbt.a:(EXCLUDE_FILE (libbtdm_app.a) .dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
. = ALIGN(4);
_ext_ram_bss_end = ABSOLUTE(.);
} > extern_ram_seg
}

View File

@ -57,6 +57,7 @@ PROVIDE ( _bss_start_btdm = 0x3ffb8000);
PROVIDE ( _bss_end_btdm = 0x3ffbff70);
PROVIDE ( _daylight = 0x3ffae0a4 );
PROVIDE ( dbg_default_handler = 0x3ff97218 );
PROVIDE ( dbg_default_state = 0x3ff97220 );
PROVIDE ( dbg_state = 0x3ffb8d5d );
PROVIDE ( DebugE256PublicKey_x = 0x3ff97428 );
PROVIDE ( DebugE256PublicKey_y = 0x3ff97408 );
@ -88,6 +89,8 @@ PROVIDE ( esp_crc8 = 0x4005d144 );
PROVIDE ( _etext = 0x4000d66c );
PROVIDE ( ets_readySet_ = 0x3ffe01f0 );
PROVIDE ( ets_startup_callback = 0x3ffe0404 );
PROVIDE ( rwip_coex_cfg = 0x3ff9914c );
PROVIDE ( rwip_priority = 0x3ff99159 );
PROVIDE ( exc_cause_table = 0x3ff991d0 );
PROVIDE ( _exit_r = 0x4000bd28 );
PROVIDE ( free = 0x4000beb8 );
@ -675,6 +678,9 @@ PROVIDE ( ld_sco_modify = 0x40031778 );
PROVIDE ( lm_cmd_cmp_send = 0x40051838 );
PROVIDE ( ld_sco_frm_cbk = 0x400349dc );
PROVIDE ( ld_acl_sniff_frm_cbk = 0x4003482c );
PROVIDE ( ld_inq_end = 0x4003ab48 );
PROVIDE ( ld_inq_sched = 0x4003aba4 );
PROVIDE ( ld_inq_frm_cbk = 0x4003ae4c );
PROVIDE ( r_ld_acl_active_hop_types_get = 0x40036e10 );
PROVIDE ( r_ld_acl_afh_confirm = 0x40036d40 );
PROVIDE ( r_ld_acl_afh_prepare = 0x40036c84 );

View File

@ -8,136 +8,136 @@
This file is responsible for placing the rodata segment in DRAM.
*/
*lib_a-utoa.o(.rodata .rodata.*)
*lib_a-longjmp.o(.rodata .rodata.*)
*lib_a-setjmp.o(.rodata .rodata.*)
*lib_a-abs.o(.rodata .rodata.*)
*lib_a-div.o(.rodata .rodata.*)
*lib_a-labs.o(.rodata .rodata.*)
*lib_a-ldiv.o(.rodata .rodata.*)
*lib_a-quorem.o(.rodata .rodata.*)
*lib_a-qsort.o(.rodata .rodata.*)
*lib_a-utoa.o(.rodata .rodata.*)
*lib_a-itoa.o(.rodata .rodata.*)
*lib_a-atoi.o(.rodata .rodata.*)
*lib_a-atol.o(.rodata .rodata.*)
*lib_a-strtol.o(.rodata .rodata.*)
*lib_a-strtoul.o(.rodata .rodata.*)
*lib_a-wcrtomb.o(.rodata .rodata.*)
*lib_a-fvwrite.o(.rodata .rodata.*)
*lib_a-wbuf.o(.rodata .rodata.*)
*lib_a-wsetup.o(.rodata .rodata.*)
*lib_a-fputwc.o(.rodata .rodata.*)
*lib_a-wctomb_r.o(.rodata .rodata.*)
*lib_a-ungetc.o(.rodata .rodata.*)
*lib_a-makebuf.o(.rodata .rodata.*)
*lib_a-fflush.o(.rodata .rodata.*)
*lib_a-refill.o(.rodata .rodata.*)
*lib_a-s_fpclassify.o(.rodata .rodata.*)
*lib_a-locale.o(.rodata .rodata.*)
*lib_a-asctime.o(.rodata .rodata.*)
*lib_a-ctime.o(.rodata .rodata.*)
*lib_a-ctime_r.o(.rodata .rodata.*)
*lib_a-lcltime.o(.rodata .rodata.*)
*lib_a-lcltime_r.o(.rodata .rodata.*)
*lib_a-gmtime.o(.rodata .rodata.*)
*lib_a-gmtime_r.o(.rodata .rodata.*)
*lib_a-strftime.o(.rodata .rodata.*)
*lib_a-mktime.o(.rodata .rodata.*)
*lib_a-syswrite.o(.rodata .rodata.*)
*lib_a-tzset_r.o(.rodata .rodata.*)
*lib_a-tzset.o(.rodata .rodata.*)
*lib_a-toupper.o(.rodata .rodata.*)
*lib_a-tolower.o(.rodata .rodata.*)
*lib_a-toascii.o(.rodata .rodata.*)
*lib_a-systimes.o(.rodata .rodata.*)
*lib_a-time.o(.rodata .rodata.*)
*lib_a-bsd_qsort_r.o(.rodata .rodata.*)
*lib_a-qsort_r.o(.rodata .rodata.*)
*lib_a-gettzinfo.o(.rodata .rodata.*)
*lib_a-strupr.o(.rodata .rodata.*)
*lib_a-asctime_r.o(.rodata .rodata.*)
*lib_a-bzero.o(.rodata .rodata.*)
*lib_a-close.o(.rodata .rodata.*)
*lib_a-creat.o(.rodata .rodata.*)
*lib_a-environ.o(.rodata .rodata.*)
*lib_a-fclose.o(.rodata .rodata.*)
*lib_a-isalnum.o(.rodata .rodata.*)
*lib_a-isalpha.o(.rodata .rodata.*)
*lib_a-isascii.o(.rodata .rodata.*)
*lib_a-isblank.o(.rodata .rodata.*)
*lib_a-iscntrl.o(.rodata .rodata.*)
*lib_a-isdigit.o(.rodata .rodata.*)
*lib_a-isgraph.o(.rodata .rodata.*)
*lib_a-islower.o(.rodata .rodata.*)
*lib_a-isprint.o(.rodata .rodata.*)
*lib_a-ispunct.o(.rodata .rodata.*)
*lib_a-isspace.o(.rodata .rodata.*)
*lib_a-isupper.o(.rodata .rodata.*)
*lib_a-memccpy.o(.rodata .rodata.*)
*lib_a-memchr.o(.rodata .rodata.*)
*lib_a-memcmp.o(.rodata .rodata.*)
*lib_a-memcpy.o(.rodata .rodata.*)
*lib_a-memmove.o(.rodata .rodata.*)
*lib_a-memrchr.o(.rodata .rodata.*)
*lib_a-memset.o(.rodata .rodata.*)
*lib_a-open.o(.rodata .rodata.*)
*lib_a-rand.o(.rodata .rodata.*)
*lib_a-rand_r.o(.rodata .rodata.*)
*lib_a-read.o(.rodata .rodata.*)
*lib_a-rshift.o(.rodata .rodata.*)
*lib_a-sbrk.o(.rodata .rodata.*)
*lib_a-srand.o(.rodata .rodata.*)
*lib_a-strcasecmp.o(.rodata .rodata.*)
*lib_a-strcasestr.o(.rodata .rodata.*)
*lib_a-strcat.o(.rodata .rodata.*)
*lib_a-strchr.o(.rodata .rodata.*)
*lib_a-strcmp.o(.rodata .rodata.*)
*lib_a-strcoll.o(.rodata .rodata.*)
*lib_a-strcpy.o(.rodata .rodata.*)
*lib_a-strcspn.o(.rodata .rodata.*)
*lib_a-strdup.o(.rodata .rodata.*)
*lib_a-strlcat.o(.rodata .rodata.*)
*lib_a-strlcpy.o(.rodata .rodata.*)
*lib_a-strlen.o(.rodata .rodata.*)
*lib_a-strlwr.o(.rodata .rodata.*)
*lib_a-strncasecmp.o(.rodata .rodata.*)
*lib_a-strncat.o(.rodata .rodata.*)
*lib_a-strncmp.o(.rodata .rodata.*)
*lib_a-strncpy.o(.rodata .rodata.*)
*lib_a-strndup.o(.rodata .rodata.*)
*lib_a-strnlen.o(.rodata .rodata.*)
*lib_a-strrchr.o(.rodata .rodata.*)
*lib_a-strsep.o(.rodata .rodata.*)
*lib_a-strspn.o(.rodata .rodata.*)
*lib_a-strstr.o(.rodata .rodata.*)
*lib_a-strtok_r.o(.rodata .rodata.*)
*lib_a-strupr.o(.rodata .rodata.*)
*lib_a-stdio.o(.rodata .rodata.*)
*lib_a-syssbrk.o(.rodata .rodata.*)
*lib_a-sysclose.o(.rodata .rodata.*)
*lib_a-sysopen.o(.rodata .rodata.*)
*creat.o(.rodata .rodata.*)
*lib_a-sysread.o(.rodata .rodata.*)
*lib_a-syswrite.o(.rodata .rodata.*)
*lib_a-impure.o(.rodata .rodata.*)
*lib_a-tzvars.o(.rodata .rodata.*)
*lib_a-sf_nan.o(.rodata .rodata.*)
*lib_a-tzcalc_limits.o(.rodata .rodata.*)
*lib_a-month_lengths.o(.rodata .rodata.*)
*lib_a-timelocal.o(.rodata .rodata.*)
*lib_a-findfp.o(.rodata .rodata.*)
*lock.o(.rodata .rodata.*)
*lib_a-getenv_r.o(.rodata .rodata.*)
*isatty.o(.rodata .rodata.*)
*lib_a-fwalk.o(.rodata .rodata.*)
*lib_a-getenv_r.o(.rodata .rodata.*)
*lib_a-tzlock.o(.rodata .rodata.*)
*lib_a-ctype_.o(.rodata .rodata.*)
*lib_a-sccl.o(.rodata .rodata.*)
*lib_a-strptime.o(.rodata .rodata.*)
*lib_a-envlock.o(.rodata .rodata.*)
*lib_a-raise.o(.rodata .rodata.*)
*lib_a-strdup_r.o(.rodata .rodata.*)
*lib_a-system.o(.rodata .rodata.*)
*lib_a-strndup_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-utoa.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-longjmp.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-setjmp.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-abs.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-div.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-labs.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-ldiv.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-quorem.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-qsort.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-utoa.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-itoa.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-atoi.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-atol.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strtol.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strtoul.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-wcrtomb.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-fvwrite.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-wbuf.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-wsetup.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-fputwc.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-wctomb_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-ungetc.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-makebuf.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-fflush.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-refill.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-s_fpclassify.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-locale.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-asctime.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-ctime.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-ctime_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-lcltime.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-lcltime_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-gmtime.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-gmtime_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strftime.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-mktime.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-syswrite.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-tzset_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-tzset.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-toupper.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-tolower.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-toascii.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-systimes.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-time.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-bsd_qsort_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-qsort_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-gettzinfo.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strupr.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-asctime_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-bzero.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-close.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-creat.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-environ.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-fclose.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-isalnum.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-isalpha.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-isascii.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-isblank.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-iscntrl.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-isdigit.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-isgraph.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-islower.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-isprint.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-ispunct.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-isspace.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-isupper.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-memccpy.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-memchr.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-memcmp.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-memcpy.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-memmove.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-memrchr.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-memset.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-open.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-rand.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-rand_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-read.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-rshift.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-sbrk.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-srand.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strcasecmp.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strcasestr.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strcat.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strchr.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strcmp.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strcoll.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strcpy.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strcspn.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strdup.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strlcat.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strlcpy.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strlen.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strlwr.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strncasecmp.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strncat.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strncmp.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strncpy.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strndup.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strnlen.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strrchr.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strsep.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strspn.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strstr.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strtok_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strupr.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-stdio.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-syssbrk.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-sysclose.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-sysopen.o(.rodata .rodata.*)
*libc-psram-workaround.a:*creat.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-sysread.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-syswrite.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-impure.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-tzvars.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-sf_nan.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-tzcalc_limits.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-month_lengths.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-timelocal.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-findfp.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lock.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-getenv_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*isatty.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-fwalk.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-getenv_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-tzlock.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-ctype_.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-sccl.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strptime.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-envlock.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-raise.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strdup_r.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-system.o(.rodata .rodata.*)
*libc-psram-workaround.a:*lib_a-strndup_r.o(.rodata .rodata.*)

View File

@ -9,136 +9,132 @@
*/
*lib_a-utoa.o(.literal .text .literal.* .text.*)
*lib_a-longjmp.o(.literal .text .literal.* .text.*)
*lib_a-setjmp.o(.literal .text .literal.* .text.*)
*lib_a-abs.o(.literal .text .literal.* .text.*)
*lib_a-div.o(.literal .text .literal.* .text.*)
*lib_a-labs.o(.literal .text .literal.* .text.*)
*lib_a-ldiv.o(.literal .text .literal.* .text.*)
*lib_a-quorem.o(.literal .text .literal.* .text.*)
*lib_a-qsort.o(.literal .text .literal.* .text.*)
*lib_a-utoa.o(.literal .text .literal.* .text.*)
*lib_a-itoa.o(.literal .text .literal.* .text.*)
*lib_a-atoi.o(.literal .text .literal.* .text.*)
*lib_a-atol.o(.literal .text .literal.* .text.*)
*lib_a-strtol.o(.literal .text .literal.* .text.*)
*lib_a-strtoul.o(.literal .text .literal.* .text.*)
*lib_a-wcrtomb.o(.literal .text .literal.* .text.*)
*lib_a-fvwrite.o(.literal .text .literal.* .text.*)
*lib_a-wbuf.o(.literal .text .literal.* .text.*)
*lib_a-wsetup.o(.literal .text .literal.* .text.*)
*lib_a-fputwc.o(.literal .text .literal.* .text.*)
*lib_a-wctomb_r.o(.literal .text .literal.* .text.*)
*lib_a-ungetc.o(.literal .text .literal.* .text.*)
*lib_a-makebuf.o(.literal .text .literal.* .text.*)
*lib_a-fflush.o(.literal .text .literal.* .text.*)
*lib_a-refill.o(.literal .text .literal.* .text.*)
*lib_a-s_fpclassify.o(.literal .text .literal.* .text.*)
*lib_a-locale.o(.literal .text .literal.* .text.*)
*lib_a-asctime.o(.literal .text .literal.* .text.*)
*lib_a-ctime.o(.literal .text .literal.* .text.*)
*lib_a-ctime_r.o(.literal .text .literal.* .text.*)
*lib_a-lcltime.o(.literal .text .literal.* .text.*)
*lib_a-lcltime_r.o(.literal .text .literal.* .text.*)
*lib_a-gmtime.o(.literal .text .literal.* .text.*)
*lib_a-gmtime_r.o(.literal .text .literal.* .text.*)
*lib_a-strftime.o(.literal .text .literal.* .text.*)
*lib_a-mktime.o(.literal .text .literal.* .text.*)
*lib_a-syswrite.o(.literal .text .literal.* .text.*)
*lib_a-tzset_r.o(.literal .text .literal.* .text.*)
*lib_a-tzset.o(.literal .text .literal.* .text.*)
*lib_a-toupper.o(.literal .text .literal.* .text.*)
*lib_a-tolower.o(.literal .text .literal.* .text.*)
*lib_a-toascii.o(.literal .text .literal.* .text.*)
*lib_a-systimes.o(.literal .text .literal.* .text.*)
*lib_a-time.o(.literal .text .literal.* .text.*)
*lib_a-bsd_qsort_r.o(.literal .text .literal.* .text.*)
*lib_a-qsort_r.o(.literal .text .literal.* .text.*)
*lib_a-gettzinfo.o(.literal .text .literal.* .text.*)
*lib_a-strupr.o(.literal .text .literal.* .text.*)
*lib_a-asctime_r.o(.literal .text .literal.* .text.*)
*lib_a-bzero.o(.literal .text .literal.* .text.*)
*lib_a-close.o(.literal .text .literal.* .text.*)
*lib_a-creat.o(.literal .text .literal.* .text.*)
*lib_a-environ.o(.literal .text .literal.* .text.*)
*lib_a-fclose.o(.literal .text .literal.* .text.*)
*lib_a-isalnum.o(.literal .text .literal.* .text.*)
*lib_a-isalpha.o(.literal .text .literal.* .text.*)
*lib_a-isascii.o(.literal .text .literal.* .text.*)
*lib_a-isblank.o(.literal .text .literal.* .text.*)
*lib_a-iscntrl.o(.literal .text .literal.* .text.*)
*lib_a-isdigit.o(.literal .text .literal.* .text.*)
*lib_a-isgraph.o(.literal .text .literal.* .text.*)
*lib_a-islower.o(.literal .text .literal.* .text.*)
*lib_a-isprint.o(.literal .text .literal.* .text.*)
*lib_a-ispunct.o(.literal .text .literal.* .text.*)
*lib_a-isspace.o(.literal .text .literal.* .text.*)
*lib_a-isupper.o(.literal .text .literal.* .text.*)
*lib_a-memccpy.o(.literal .text .literal.* .text.*)
*lib_a-memchr.o(.literal .text .literal.* .text.*)
*lib_a-memcmp.o(.literal .text .literal.* .text.*)
*lib_a-memcpy.o(.literal .text .literal.* .text.*)
*lib_a-memmove.o(.literal .text .literal.* .text.*)
*lib_a-memrchr.o(.literal .text .literal.* .text.*)
*lib_a-memset.o(.literal .text .literal.* .text.*)
*lib_a-open.o(.literal .text .literal.* .text.*)
*lib_a-rand.o(.literal .text .literal.* .text.*)
*lib_a-rand_r.o(.literal .text .literal.* .text.*)
*lib_a-read.o(.literal .text .literal.* .text.*)
*lib_a-rshift.o(.literal .text .literal.* .text.*)
*lib_a-sbrk.o(.literal .text .literal.* .text.*)
*lib_a-srand.o(.literal .text .literal.* .text.*)
*lib_a-strcasecmp.o(.literal .text .literal.* .text.*)
*lib_a-strcasestr.o(.literal .text .literal.* .text.*)
*lib_a-strcat.o(.literal .text .literal.* .text.*)
*lib_a-strchr.o(.literal .text .literal.* .text.*)
*lib_a-strcmp.o(.literal .text .literal.* .text.*)
*lib_a-strcoll.o(.literal .text .literal.* .text.*)
*lib_a-strcpy.o(.literal .text .literal.* .text.*)
*lib_a-strcspn.o(.literal .text .literal.* .text.*)
*lib_a-strdup.o(.literal .text .literal.* .text.*)
*lib_a-strlcat.o(.literal .text .literal.* .text.*)
*lib_a-strlcpy.o(.literal .text .literal.* .text.*)
*lib_a-strlen.o(.literal .text .literal.* .text.*)
*lib_a-strlwr.o(.literal .text .literal.* .text.*)
*lib_a-strncasecmp.o(.literal .text .literal.* .text.*)
*lib_a-strncat.o(.literal .text .literal.* .text.*)
*lib_a-strncmp.o(.literal .text .literal.* .text.*)
*lib_a-strncpy.o(.literal .text .literal.* .text.*)
*lib_a-strndup.o(.literal .text .literal.* .text.*)
*lib_a-strnlen.o(.literal .text .literal.* .text.*)
*lib_a-strrchr.o(.literal .text .literal.* .text.*)
*lib_a-strsep.o(.literal .text .literal.* .text.*)
*lib_a-strspn.o(.literal .text .literal.* .text.*)
*lib_a-strstr.o(.literal .text .literal.* .text.*)
*lib_a-strtok_r.o(.literal .text .literal.* .text.*)
*lib_a-strupr.o(.literal .text .literal.* .text.*)
*lib_a-stdio.o(.literal .text .literal.* .text.*)
*lib_a-syssbrk.o(.literal .text .literal.* .text.*)
*lib_a-sysclose.o(.literal .text .literal.* .text.*)
*lib_a-sysopen.o(.literal .text .literal.* .text.*)
*creat.o(.literal .text .literal.* .text.*)
*lib_a-sysread.o(.literal .text .literal.* .text.*)
*lib_a-syswrite.o(.literal .text .literal.* .text.*)
*lib_a-impure.o(.literal .text .literal.* .text.*)
*lib_a-tzvars.o(.literal .text .literal.* .text.*)
*lib_a-sf_nan.o(.literal .text .literal.* .text.*)
*lib_a-tzcalc_limits.o(.literal .text .literal.* .text.*)
*lib_a-month_lengths.o(.literal .text .literal.* .text.*)
*lib_a-timelocal.o(.literal .text .literal.* .text.*)
*lib_a-findfp.o(.literal .text .literal.* .text.*)
*lock.o(.literal .text .literal.* .text.*)
*lib_a-getenv_r.o(.literal .text .literal.* .text.*)
*isatty.o(.literal .text .literal.* .text.*)
*lib_a-fwalk.o(.literal .text .literal.* .text.*)
*lib_a-getenv_r.o(.literal .text .literal.* .text.*)
*lib_a-tzlock.o(.literal .text .literal.* .text.*)
*lib_a-ctype_.o(.literal .text .literal.* .text.*)
*lib_a-sccl.o(.literal .text .literal.* .text.*)
*lib_a-strptime.o(.literal .text .literal.* .text.*)
*lib_a-envlock.o(.literal .text .literal.* .text.*)
*lib_a-raise.o(.literal .text .literal.* .text.*)
*lib_a-strdup_r.o(.literal .text .literal.* .text.*)
*lib_a-system.o(.literal .text .literal.* .text.*)
*lib_a-strndup_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-utoa.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-longjmp.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-setjmp.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-abs.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-div.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-labs.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-ldiv.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-quorem.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-utoa.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-itoa.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-atoi.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-atol.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strtol.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strtoul.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-wcrtomb.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-fvwrite.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-wbuf.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-wsetup.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-fputwc.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-wctomb_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-ungetc.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-makebuf.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-fflush.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-refill.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-s_fpclassify.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-asctime.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-ctime.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-ctime_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-lcltime.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-lcltime_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-gmtime.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-gmtime_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strftime.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-mktime.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-syswrite.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-tzset_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-tzset.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-toupper.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-tolower.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-toascii.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-systimes.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-time.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-gettzinfo.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strupr.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-asctime_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-bzero.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-close.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-creat.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-environ.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-fclose.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-isalnum.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-isalpha.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-isascii.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-isblank.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-iscntrl.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-isdigit.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-isgraph.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-islower.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-isprint.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-ispunct.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-isspace.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-isupper.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-memccpy.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-memchr.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-memcmp.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-memcpy.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-memmove.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-memrchr.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-memset.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-open.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-rand.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-rand_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-read.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-rshift.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-sbrk.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-srand.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strcasecmp.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strcasestr.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strcat.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strchr.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strcmp.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strcoll.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strcpy.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strcspn.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strdup.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strlcat.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strlcpy.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strlen.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strlwr.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strncasecmp.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strncat.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strncmp.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strncpy.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strndup.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strnlen.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strrchr.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strsep.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strspn.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strstr.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strtok_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strupr.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-stdio.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-syssbrk.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-sysclose.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-sysopen.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*creat.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-sysread.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-syswrite.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-impure.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-tzvars.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-sf_nan.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-tzcalc_limits.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-month_lengths.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-timelocal.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-findfp.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lock.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-getenv_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*isatty.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-fwalk.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-getenv_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-tzlock.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-ctype_.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-sccl.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strptime.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-envlock.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-raise.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strdup_r.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-system.o(.literal .text .literal.* .text.*)
*libc-psram-workaround.a:*lib_a-strndup_r.o(.literal .text .literal.* .text.*)

View File

@ -188,6 +188,7 @@ static const char *edesc[] = {
static void commonErrorHandler(XtExcFrame *frame);
static inline void disableAllWdts();
static void illegal_instruction_helper(XtExcFrame *frame);
//The fact that we've panic'ed probably means the other CPU is now running wild, possibly
//messing up the serial output, so we stall it here.
@ -357,11 +358,37 @@ void xt_unhandled_exception(XtExcFrame *frame)
return;
}
panicPutStr(". Exception was unhandled.\r\n");
if (exccause == 0 /* IllegalInstruction */) {
illegal_instruction_helper(frame);
}
esp_reset_reason_set_hint(ESP_RST_PANIC);
}
commonErrorHandler(frame);
}
static void illegal_instruction_helper(XtExcFrame *frame)
{
/* Print out memory around the instruction word */
uint32_t epc = frame->pc;
epc = (epc & ~0x3) - 4;
/* check that the address was sane */
if (epc < SOC_IROM_MASK_LOW || epc >= SOC_IROM_HIGH) {
return;
}
volatile uint32_t* pepc = (uint32_t*)epc;
panicPutStr("Memory dump at 0x");
panicPutHex(epc);
panicPutStr(": ");
panicPutHex(*pepc);
panicPutStr(" ");
panicPutHex(*(pepc + 1));
panicPutStr(" ");
panicPutHex(*(pepc + 2));
panicPutStr("\r\n");
}
/*
If watchdogs are enabled, the panic handler runs the risk of getting aborted pre-emptively because

View File

@ -48,7 +48,7 @@ static _lock_t s_phy_rf_init_lock;
/* Bit mask of modules needing to call phy_rf_init */
static uint32_t s_module_phy_rf_init = 0;
/* Whether modern sleep in turned on */
/* Whether modem sleep is turned on */
static volatile bool s_is_phy_rf_en = false;
/* Bit mask of modules needing to enter modem sleep mode */
@ -64,6 +64,9 @@ static volatile bool s_is_modem_sleep_en = false;
static _lock_t s_modem_sleep_lock;
/* time stamp updated when the PHY/RF is turned on */
static int64_t s_phy_rf_en_ts = 0;
uint32_t IRAM_ATTR phy_enter_critical(void)
{
return portENTER_CRITICAL_NESTED();
@ -74,16 +77,20 @@ void IRAM_ATTR phy_exit_critical(uint32_t level)
portEXIT_CRITICAL_NESTED(level);
}
static inline void phy_update_wifi_mac_time(bool en_clock_stopped)
int64_t esp_phy_rf_get_on_ts(void)
{
return s_phy_rf_en_ts;
}
static inline void phy_update_wifi_mac_time(bool en_clock_stopped, int64_t now)
{
static uint32_t s_common_clock_disable_time = 0;
if (en_clock_stopped) {
s_common_clock_disable_time = esp_timer_get_time();
s_common_clock_disable_time = (uint32_t)now;
} else {
if (s_common_clock_disable_time) {
uint64_t now = esp_timer_get_time();
uint32_t diff = now - s_common_clock_disable_time;
uint32_t diff = (uint64_t)now - s_common_clock_disable_time;
esp_wifi_internal_update_mac_time(diff);
s_common_clock_disable_time = 0;
@ -135,8 +142,10 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibrat
}
}
if (s_is_phy_rf_en == true){
// Update time stamp
s_phy_rf_en_ts = esp_timer_get_time();
// Update WiFi MAC time before WiFi/BT common clock is enabled
phy_update_wifi_mac_time( false );
phy_update_wifi_mac_time(false, s_phy_rf_en_ts);
// Enable WiFi/BT common peripheral clock
periph_module_enable(PERIPH_WIFI_BT_COMMON_MODULE);
phy_set_wifi_mode_only(0);
@ -229,7 +238,7 @@ esp_err_t esp_phy_rf_deinit(phy_rf_module_t module)
// Disable PHY and RF.
phy_close_rf();
// Update WiFi MAC time before disalbe WiFi/BT common peripheral clock
phy_update_wifi_mac_time(true);
phy_update_wifi_mac_time(true, esp_timer_get_time());
// Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG
periph_module_disable(PERIPH_WIFI_BT_COMMON_MODULE);
}

View File

@ -81,11 +81,20 @@ static uint32_t s_ccount_div;
static uint32_t s_ccount_mul;
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
/* Indicates if light sleep entry was successful for given CPU.
/* Indicates if light sleep entry was skipped in vApplicationSleep for given CPU.
* This in turn gets used in IDLE hook to decide if `waiti` needs
* to be invoked or not.
*/
static bool s_entered_light_sleep[portNUM_PROCESSORS];
static bool s_skipped_light_sleep[portNUM_PROCESSORS];
#if portNUM_PROCESSORS == 2
/* When light sleep is finished on one CPU, it is possible that the other CPU
* will enter light sleep again very soon, before interrupts on the first CPU
* get a chance to run. To avoid such situation, set a flag for the other CPU to
* skip light sleep attempt.
*/
static bool s_skip_light_sleep[portNUM_PROCESSORS];
#endif // portNUM_PROCESSORS == 2
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
/* Indicates to the ISR hook that CCOMPARE needs to be updated on the given CPU.
@ -465,10 +474,14 @@ void esp_pm_impl_waiti()
{
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
int core_id = xPortGetCoreID();
if (!s_entered_light_sleep[core_id]) {
if (s_skipped_light_sleep[core_id]) {
asm("waiti 0");
} else {
s_entered_light_sleep[core_id] = false;
/* Interrupt took the CPU out of waiti and s_rtos_lock_handle[core_id]
* is now taken. However since we are back to idle task, we can release
* the lock so that vApplicationSleep can attempt to enter light sleep.
*/
esp_pm_impl_idle_hook();
s_skipped_light_sleep[core_id] = false;
}
#else
asm("waiti 0");
@ -477,10 +490,35 @@ void esp_pm_impl_waiti()
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
static inline bool IRAM_ATTR should_skip_light_sleep(int core_id)
{
#if portNUM_PROCESSORS == 2
if (s_skip_light_sleep[core_id]) {
s_skip_light_sleep[core_id] = false;
s_skipped_light_sleep[core_id] = true;
return true;
}
#endif // portNUM_PROCESSORS == 2
if (s_mode != PM_MODE_LIGHT_SLEEP || s_is_switching) {
s_skipped_light_sleep[core_id] = true;
} else {
s_skipped_light_sleep[core_id] = false;
}
return s_skipped_light_sleep[core_id];
}
static inline void IRAM_ATTR other_core_should_skip_light_sleep(int core_id)
{
#if portNUM_PROCESSORS == 2
s_skip_light_sleep[!core_id] = true;
#endif
}
void IRAM_ATTR vApplicationSleep( TickType_t xExpectedIdleTime )
{
portENTER_CRITICAL(&s_switch_lock);
if (s_mode == PM_MODE_LIGHT_SLEEP && !s_is_switching) {
int core_id = xPortGetCoreID();
if (!should_skip_light_sleep(core_id)) {
/* Calculate how much we can sleep */
int64_t next_esp_timer_alarm = esp_timer_get_next_alarm();
int64_t now = esp_timer_get_time();
@ -494,7 +532,6 @@ void IRAM_ATTR vApplicationSleep( TickType_t xExpectedIdleTime )
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
#endif
/* Enter sleep */
int core_id = xPortGetCoreID();
ESP_PM_TRACE_ENTER(SLEEP, core_id);
int64_t sleep_start = esp_timer_get_time();
esp_light_sleep_start();
@ -516,7 +553,7 @@ void IRAM_ATTR vApplicationSleep( TickType_t xExpectedIdleTime )
;
}
}
s_entered_light_sleep[core_id] = true;
other_core_should_skip_light_sleep(core_id);
}
}
portEXIT_CRITICAL(&s_switch_lock);

View File

@ -0,0 +1,8 @@
if(CONFIG_SPIRAM_CACHE_WORKAROUND)
# We do this here as well as in CMakeLists.txt, because targets that
# are not part of the ESP-IDF build system (for cases where a generic
# non-IDF CMakeLists.txt file is imported into a component) don't depend
# on the esp32 component so don't get the extra flag. This handles that case.
add_compile_options(-mfix-esp32-psram-cache-issue)
endif()

View File

@ -1,5 +1,5 @@
/*
Abstraction layer for spi-ram. For now, it's no more than a stub for the spiram_psram functions, but if
Abstraction layer for spi-ram. For now, it's no more than a stub for the spiram_psram functions, but if
we add more types of external RAM memory, this can be made into a more intelligent dispatcher.
*/
@ -61,7 +61,7 @@ static const char* TAG = "spiram";
#endif
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
extern int _ext_ram_bss_start, _ext_ram_bss_end;
extern uint8_t _ext_ram_bss_start, _ext_ram_bss_end;
#endif
static bool spiram_inited=false;
@ -131,6 +131,8 @@ esp_spiram_size_t esp_spiram_get_chip_size()
}
psram_size_t psram_size = psram_get_size();
switch (psram_size) {
case PSRAM_SIZE_16MBITS:
return ESP_SPIRAM_SIZE_16MBITS;
case PSRAM_SIZE_32MBITS:
return ESP_SPIRAM_SIZE_32MBITS;
case PSRAM_SIZE_64MBITS:
@ -159,7 +161,7 @@ esp_err_t esp_spiram_init()
}
#endif
ESP_EARLY_LOGI(TAG, "Found %dMBit SPI RAM device",
ESP_EARLY_LOGI(TAG, "Found %dMBit SPI RAM device",
(esp_spiram_get_size()*8)/(1024*1024));
ESP_EARLY_LOGI(TAG, "SPI RAM mode: %s", PSRAM_SPEED == PSRAM_CACHE_F40M_S40M ? "flash 40m sram 40m" : \
PSRAM_SPEED == PSRAM_CACHE_F80M_S40M ? "flash 80m sram 40m" : \
@ -214,6 +216,7 @@ esp_err_t esp_spiram_reserve_dma_pool(size_t size) {
size_t esp_spiram_get_size()
{
psram_size_t size=esp_spiram_get_chip_size();
if (size==PSRAM_SIZE_16MBITS) return 2*1024*1024;
if (size==PSRAM_SIZE_32MBITS) return 4*1024*1024;
if (size==PSRAM_SIZE_64MBITS) return 8*1024*1024;
return CONFIG_SPIRAM_SIZE;
@ -225,7 +228,7 @@ size_t esp_spiram_get_size()
Note that this routine assumes some unique mapping for the first 2 banks of the PSRAM memory range, as well as the
2 banks after the 2 MiB mark.
*/
void IRAM_ATTR esp_spiram_writeback_cache()
void IRAM_ATTR esp_spiram_writeback_cache()
{
int x;
volatile int i=0;
@ -234,7 +237,7 @@ void IRAM_ATTR esp_spiram_writeback_cache()
if (!spiram_inited) return;
//We need cache enabled for this to work. Re-enable it if needed; make sure we
//We need cache enabled for this to work. Re-enable it if needed; make sure we
//disable it again on exit as well.
if (DPORT_REG_GET_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE)==0) {
cache_was_disabled|=(1<<0);
@ -257,10 +260,10 @@ void IRAM_ATTR esp_spiram_writeback_cache()
}
#else
/*
Low/high psram cache mode uses one 32K cache for the lowest 2MiB of SPI flash and another 32K for the highest
Low/high psram cache mode uses one 32KB cache for the lowest 2MiB of SPI flash and another 32K for the highest
2MiB. Clear this by reading from both regions.
Note: this assumes the amount of external RAM is >2M. If it is 2M or less, what this code does is undefined. If
we ever support external RAM chips of 2M or smaller, this may need adjusting.
Note: this assumes the amount of external RAM is >2MB. If it is 2MB or less, what this code does is undefined. If
we ever support external RAM chips of 2MB or smaller, this may need adjusting.
*/
for (x=0; x<1024*64; x+=32) {
i+=psram[x];
@ -280,4 +283,15 @@ void IRAM_ATTR esp_spiram_writeback_cache()
#endif
}
/**
* @brief If SPI RAM(PSRAM) has been initialized
*
* @return true SPI RAM has been initialized successfully
* @return false SPI RAM hasn't been initialized or initialized failed
*/
bool esp_spiram_is_initialized()
{
return spiram_inited;
}
#endif

View File

@ -65,38 +65,110 @@ typedef enum {
#define PSRAM_ID_EID_M 0xff
#define PSRAM_ID_EID_S 16
#define PSRAM_KGD(id) (((id) >> PSRAM_ID_KGD_S) & PSRAM_ID_KGD_M)
#define PSRAM_EID(id) (((id) >> PSRAM_ID_EID_S) & PSRAM_ID_EID_M)
#define PSRAM_IS_VALID(id) (PSRAM_KGD(id) == PSRAM_ID_KGD)
// Use the [7:5](bit7~bit5) of EID to distinguish the psram size:
//
// BIT7 | BIT6 | BIT5 | SIZE(MBIT)
// -------------------------------------
// 0 | 0 | 0 | 16
// 0 | 0 | 1 | 32
// 0 | 1 | 0 | 64
#define PSRAM_EID_SIZE_M 0x07
#define PSRAM_EID_SIZE_S 5
// PSRAM_EID = 0x26 or 0x4x ----> 64MBit psram
// PSRAM_EID = 0x20 ------------> 32MBit psram
#define PSRAM_IS_64MBIT(id) ((PSRAM_EID(id) == 0x26) || ((PSRAM_EID(id) & 0xf0) == 0x40))
typedef enum {
PSRAM_EID_SIZE_16MBITS = 0,
PSRAM_EID_SIZE_32MBITS = 1,
PSRAM_EID_SIZE_64MBITS = 2,
} psram_eid_size_t;
#define PSRAM_KGD(id) (((id) >> PSRAM_ID_KGD_S) & PSRAM_ID_KGD_M)
#define PSRAM_EID(id) (((id) >> PSRAM_ID_EID_S) & PSRAM_ID_EID_M)
#define PSRAM_SIZE_ID(id) ((PSRAM_EID(id) >> PSRAM_EID_SIZE_S) & PSRAM_EID_SIZE_M)
#define PSRAM_IS_VALID(id) (PSRAM_KGD(id) == PSRAM_ID_KGD)
// For the old version 32Mbit psram, using the spicial driver */
#define PSRAM_IS_32MBIT_VER0(id) (PSRAM_EID(id) == 0x20)
#define PSRAM_IS_64MBIT_TRIAL(id) (PSRAM_EID(id) == 0x26)
// IO-pins for PSRAM. These need to be in the VDD_SIO power domain because all chips we
// currently support are 1.8V parts.
// IO-pins for PSRAM.
// WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines
// hardcode the flash pins as well, making this code incompatible with either a setup
// that has the flash on non-standard pins or ESP32s with built-in flash.
#define FLASH_CLK_IO 6 //Psram clock is a delayed version of this in 40MHz mode
#define FLASH_CS_IO 11
#define PSRAM_CLK_IO 17
#define PSRAM_CS_IO 16
#define PSRAM_SPIQ_IO 7
#define PSRAM_SPID_IO 8
#define PSRAM_SPIWP_IO 10
#define PSRAM_SPIHD_IO 9
#define FLASH_CLK_IO 6
#define FLASH_CS_IO 11
#define FLASH_SPIQ_SD0_IO 7
#define FLASH_SPID_SD1_IO 8
#define FLASH_SPIWP_SD3_IO 10
#define FLASH_SPIHD_SD2_IO 9
#define PSRAM_CLK_IO 17
#define PSRAM_CS_IO 16
#define PSRAM_SPIQ_SD0_IO 7
#define PSRAM_SPID_SD1_IO 8
#define PSRAM_SPIWP_SD3_IO 10
#define PSRAM_SPIHD_SD2_IO 9
// IO-pins of ESP32-PICO-D4 for PSRAM. PSRAM share clock with flash.
// The CS IO can be overwrite via menuconfig.
#define PICO_FLASH_CLK_IO 6
#define PICO_FLASH_CS_IO 16
#define PICO_FLASH_SPIQ_SD0_IO 17
#define PICO_FLASH_SPID_SD1_IO 8
#define PICO_FLASH_SPIWP_SD3_IO 7
#define PICO_FLASH_SPIHD_SD2_IO 11
#define PICO_PSRAM_CLK_IO 6
#define PICO_PSRAM_CS_IO CONFIG_PICO_PSRAM_CS_IO
#define PICO_PSRAM_SPIQ_SD0_IO 17
#define PICO_PSRAM_SPID_SD1_IO 8
#define PICO_PSRAM_SPIWP_SD3_IO 7
#define PICO_PSRAM_SPIHD_SD2_IO 11
typedef struct {
uint8_t flash_clk_io;
uint8_t flash_cs_io;
uint8_t flash_spiq_sd0_io;
uint8_t flash_spid_sd1_io;
uint8_t flash_spiwp_sd3_io;
uint8_t flash_spihd_sd2_io;
uint8_t psram_clk_io;
uint8_t psram_cs_io;
uint8_t psram_spiq_sd0_io;
uint8_t psram_spid_sd1_io;
uint8_t psram_spiwp_sd3_io;
uint8_t psram_spihd_sd2_io;
} psram_io_t;
#define PSRAM_INTERNAL_IO_28 28
#define PSRAM_INTERNAL_IO_29 29
#define PSRAM_IO_MATRIX_DUMMY_40M 1
#define PSRAM_IO_MATRIX_DUMMY_80M 2
#define _SPI_CACHE_PORT 0
#define _SPI_FLASH_PORT 1
#define _SPI_80M_CLK_DIV 1
#define _SPI_40M_CLK_DIV 2
#define _SPI_CACHE_PORT 0
#define _SPI_FLASH_PORT 1
#define _SPI_80M_CLK_DIV 1
#define _SPI_40M_CLK_DIV 2
//For 4MB PSRAM, we need one more SPI host, select which one to use by kconfig
#ifdef CONFIG_SPIRAM_OCCUPY_HSPI_HOST
#define PSRAM_SPI_MODULE PERIPH_HSPI_MODULE
#define PSRAM_SPI_HOST HSPI_HOST
#define PSRAM_CLK_SIGNAL HSPICLK_OUT_IDX
#define PSRAM_SPI_NUM PSRAM_SPI_2
#define PSRAM_SPICLKEN DPORT_SPI2_CLK_EN
#elif defined CONFIG_SPIRAM_OCCUPY_VSPI_HOST
#define PSRAM_SPI_MODULE PERIPH_VSPI_MODULE
#define PSRAM_SPI_HOST VSPI_HOST
#define PSRAM_CLK_SIGNAL VSPICLK_OUT_IDX
#define PSRAM_SPI_NUM PSRAM_SPI_3
#define PSRAM_SPICLKEN DPORT_SPI3_CLK_EN
#else //set to SPI avoid HSPI and VSPI being used
#define PSRAM_SPI_MODULE PERIPH_SPI_MODULE
#define PSRAM_SPI_HOST SPI_HOST
#define PSRAM_CLK_SIGNAL SPICLK_OUT_IDX
#define PSRAM_SPI_NUM PSRAM_SPI_1
#define PSRAM_SPICLKEN DPORT_SPI01_CLK_EN
#endif
static const char* TAG = "psram";
typedef enum {
@ -223,8 +295,6 @@ static uint32_t backup_usr[3];
static uint32_t backup_usr1[3];
static uint32_t backup_usr2[3];
//setup spi command/addr/data/dummy in user mode
static int psram_cmd_config(psram_spi_num_t spi_num, psram_cmd_t* pInData)
{
@ -444,7 +514,7 @@ void IRAM_ATTR psram_spi_init(psram_spi_num_t spi_num, psram_cache_mode_t mode)
* Psram mode init will overwrite original flash speed mode, so that it is possible to change psram and flash speed after OTA.
* Flash read mode(QIO/QOUT/DIO/DOUT) will not be changed in app bin. It is decided by bootloader, OTA can not change this mode.
*/
static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
static void IRAM_ATTR psram_gpio_config(psram_io_t psram_io, psram_cache_mode_t mode)
{
int spi_cache_dummy = 0;
uint32_t rd_mode_reg = READ_PERI_REG(SPI_CTRL_REG(0));
@ -457,15 +527,15 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
}
// In bootloader, all the signals are already configured,
// We keep the following code in case the bootloader is some older version.
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
gpio_matrix_out(PSRAM_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
gpio_matrix_in(PSRAM_SPIQ_IO, SPIQ_IN_IDX, 0);
gpio_matrix_out(PSRAM_SPID_IO, SPID_OUT_IDX, 0, 0);
gpio_matrix_in(PSRAM_SPID_IO, SPID_IN_IDX, 0);
gpio_matrix_out(PSRAM_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
gpio_matrix_in(PSRAM_SPIWP_IO, SPIWP_IN_IDX, 0);
gpio_matrix_out(PSRAM_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
gpio_matrix_in(PSRAM_SPIHD_IO, SPIHD_IN_IDX, 0);
gpio_matrix_out(psram_io.flash_cs_io, SPICS0_OUT_IDX, 0, 0);
gpio_matrix_out(psram_io.psram_spiq_sd0_io, SPIQ_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io.psram_spiq_sd0_io, SPIQ_IN_IDX, 0);
gpio_matrix_out(psram_io.psram_spid_sd1_io, SPID_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io.psram_spid_sd1_io, SPID_IN_IDX, 0);
gpio_matrix_out(psram_io.psram_spiwp_sd3_io, SPIWP_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io.psram_spiwp_sd3_io, SPIWP_IN_IDX, 0);
gpio_matrix_out(psram_io.psram_spihd_sd2_io, SPIHD_OUT_IDX, 0, 0);
gpio_matrix_in(psram_io.psram_spihd_sd2_io, SPIHD_IN_IDX, 0);
switch (mode) {
case PSRAM_CACHE_F80M_S40M:
@ -476,8 +546,8 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT);
esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT);
//set drive ability for clock
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 2, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV, 2, FUN_DRV_S);
break;
case PSRAM_CACHE_F80M_S80M:
extra_dummy = PSRAM_IO_MATRIX_DUMMY_80M;
@ -487,8 +557,8 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT);
esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_FLASH_PORT);
//set drive ability for clock
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV, 3, FUN_DRV_S);
break;
case PSRAM_CACHE_F40M_S40M:
extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M;
@ -498,8 +568,8 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_CACHE_PORT);
esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT);
//set drive ability for clock
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 2, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 2, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV, 2, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV, 2, FUN_DRV_S);
break;
default:
break;
@ -507,21 +577,24 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_USR_DUMMY); // dummy en
//select pin function gpio
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spiq_sd0_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spid_sd1_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spihd_sd2_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_spiwp_sd3_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.flash_cs_io], PIN_FUNC_GPIO);
//flash clock signal should come from IO MUX.
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUNC_SD_CLK_SPICLK);
}
psram_size_t psram_get_size()
{
if (PSRAM_IS_32MBIT_VER0(s_psram_id)) {
return PSRAM_SIZE_32MBITS;
} else if (PSRAM_IS_64MBIT(s_psram_id)) {
if ((PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_64MBITS) || PSRAM_IS_64MBIT_TRIAL(s_psram_id)) {
return PSRAM_SIZE_64MBITS;
} else if (PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_32MBITS) {
return PSRAM_SIZE_32MBITS;
} else if (PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_16MBITS) {
return PSRAM_SIZE_16MBITS;
} else {
return PSRAM_SIZE_MAX;
}
@ -530,52 +603,80 @@ psram_size_t psram_get_size()
//psram gpio init , different working frequency we have different solutions
esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode) //psram init
{
psram_io_t psram_io;
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
uint32_t pkg_ver = chip_ver & 0x7;
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
ESP_EARLY_LOGE(TAG, "ESP32D2WD do not support psram yet");
return ESP_FAIL;
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
ESP_EARLY_LOGE(TAG, "ESP32PICOD2 do not support psram yet");
return ESP_FAIL;
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
ESP_EARLY_LOGE(TAG, "ESP32PICOD4 do not support psram yet");
return ESP_FAIL;
} else if ((pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) || (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4)) {
ESP_EARLY_LOGI(TAG, "This chip is ESP32-PICO");
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
if (cfg.tieh != RTC_VDDSDIO_TIEH_3_3V) {
ESP_EARLY_LOGE(TAG, "VDDSDIO is not 3.3V");
return ESP_FAIL;
}
psram_io.flash_clk_io = PICO_FLASH_CLK_IO;
psram_io.flash_cs_io = PICO_FLASH_CS_IO;
psram_io.flash_spiq_sd0_io = PICO_FLASH_SPIQ_SD0_IO;
psram_io.flash_spid_sd1_io = PICO_FLASH_SPID_SD1_IO;
psram_io.flash_spiwp_sd3_io = PICO_FLASH_SPIWP_SD3_IO;
psram_io.flash_spihd_sd2_io = PICO_FLASH_SPIHD_SD2_IO;
psram_io.psram_clk_io = PICO_PSRAM_CLK_IO;
psram_io.psram_cs_io = PICO_PSRAM_CS_IO;
psram_io.psram_spiq_sd0_io = PICO_PSRAM_SPIQ_SD0_IO;
psram_io.psram_spid_sd1_io = PICO_PSRAM_SPID_SD1_IO;
psram_io.psram_spiwp_sd3_io = PICO_PSRAM_SPIWP_SD3_IO;
psram_io.psram_spihd_sd2_io = PICO_PSRAM_SPIHD_SD2_IO;
s_clk_mode = PSRAM_CLK_MODE_NORM;
} else {
psram_io.flash_clk_io = FLASH_CLK_IO;
psram_io.flash_cs_io = FLASH_CS_IO;
psram_io.flash_spiq_sd0_io = FLASH_SPIQ_SD0_IO;
psram_io.flash_spid_sd1_io = FLASH_SPID_SD1_IO;
psram_io.flash_spiwp_sd3_io = FLASH_SPIWP_SD3_IO;
psram_io.flash_spihd_sd2_io = FLASH_SPIHD_SD2_IO;
psram_io.psram_clk_io = PSRAM_CLK_IO;
psram_io.psram_cs_io = PSRAM_CS_IO;
psram_io.psram_spiq_sd0_io = PSRAM_SPIQ_SD0_IO;
psram_io.psram_spid_sd1_io = PSRAM_SPID_SD1_IO;
psram_io.psram_spiwp_sd3_io = PSRAM_SPIWP_SD3_IO;
psram_io.psram_spihd_sd2_io = PSRAM_SPIHD_SD2_IO;
}
WRITE_PERI_REG(GPIO_ENABLE_W1TC_REG, BIT(PSRAM_CLK_IO) | BIT(PSRAM_CS_IO)); //DISABLE OUPUT FOR IO16/17
WRITE_PERI_REG(GPIO_ENABLE_W1TC_REG, BIT(psram_io.psram_clk_io) | BIT(psram_io.psram_cs_io)); //DISABLE OUPUT FOR IO16/17
assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now.");
s_psram_mode = mode;
periph_module_enable(PERIPH_SPI_MODULE);
WRITE_PERI_REG(SPI_EXT3_REG(0), 0x1);
CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_USR_PREP_HOLD_M);
psram_spi_init(PSRAM_SPI_1, mode);
CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_CS_HOLD);
gpio_matrix_out(psram_io.psram_cs_io, SPICS1_OUT_IDX, 0, 0);
switch (mode) {
case PSRAM_CACHE_F80M_S80M:
psram_spi_init(PSRAM_SPI_1, mode);
CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_CS_HOLD);
gpio_matrix_out(PSRAM_CS_IO, SPICS1_OUT_IDX, 0, 0);
gpio_matrix_out(PSRAM_CLK_IO, SPICLK_OUT_IDX, 0, 0);
gpio_matrix_out(psram_io.psram_clk_io, SPICLK_OUT_IDX, 0, 0);
break;
case PSRAM_CACHE_F80M_S40M:
case PSRAM_CACHE_F40M_S40M:
default:
psram_spi_init(PSRAM_SPI_1, mode);
CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_CS_HOLD);
gpio_matrix_out(PSRAM_CS_IO, SPICS1_OUT_IDX, 0, 0);
/* We need to delay CLK to the PSRAM with respect to the clock signal as output by the SPI peripheral.
We do this by routing it signal to signal 224/225, which are used as a loopback; the extra run through
the GPIO matrix causes the delay. We use GPIO20 (which is not in any package but has pad logic in
silicon) as a temporary pad for this. So the signal path is:
SPI CLK --> GPIO28 --> signal224(in then out) --> internal GPIO29 --> signal225(in then out) --> GPIO17(PSRAM CLK)
*/
gpio_matrix_out(PSRAM_INTERNAL_IO_28, SPICLK_OUT_IDX, 0, 0);
gpio_matrix_in(PSRAM_INTERNAL_IO_28, SIG_IN_FUNC224_IDX, 0);
gpio_matrix_out(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC224_IDX, 0, 0);
gpio_matrix_in(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC225_IDX, 0);
gpio_matrix_out(PSRAM_CLK_IO, SIG_IN_FUNC225_IDX, 0, 0);
if (s_clk_mode == PSRAM_CLK_MODE_DCLK) {
/* We need to delay CLK to the PSRAM with respect to the clock signal as output by the SPI peripheral.
We do this by routing it signal to signal 224/225, which are used as a loopback; the extra run through
the GPIO matrix causes the delay. We use GPIO20 (which is not in any package but has pad logic in
silicon) as a temporary pad for this. So the signal path is:
SPI CLK --> GPIO28 --> signal224(in then out) --> internal GPIO29 --> signal225(in then out) --> GPIO17(PSRAM CLK)
*/
gpio_matrix_out(PSRAM_INTERNAL_IO_28, SPICLK_OUT_IDX, 0, 0);
gpio_matrix_in(PSRAM_INTERNAL_IO_28, SIG_IN_FUNC224_IDX, 0);
gpio_matrix_out(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC224_IDX, 0, 0);
gpio_matrix_in(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC225_IDX, 0);
gpio_matrix_out(psram_io.psram_clk_io, SIG_IN_FUNC225_IDX, 0, 0);
} else {
gpio_matrix_out(psram_io.psram_clk_io, SPICLK_OUT_IDX, 0, 0);
}
break;
}
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
@ -591,10 +692,10 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
}
#endif
CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_CS_SETUP_M);
psram_gpio_config(mode);
WRITE_PERI_REG(GPIO_ENABLE_W1TS_REG, BIT(PSRAM_CS_IO)| BIT(PSRAM_CLK_IO));
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CS_IO], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], PIN_FUNC_GPIO);
psram_gpio_config(psram_io, mode);
WRITE_PERI_REG(GPIO_ENABLE_W1TS_REG, BIT(psram_io.psram_cs_io) | BIT(psram_io.psram_clk_io));
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.psram_cs_io], PIN_FUNC_GPIO);
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], PIN_FUNC_GPIO);
psram_read_id(&s_psram_id);
if (!PSRAM_IS_VALID(s_psram_id)) {
@ -603,22 +704,17 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
uint32_t flash_id = g_rom_flashchip.device_id;
if (flash_id == FLASH_ID_GD25LQ32C) {
// Set drive ability for 1.8v flash in 80Mhz.
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CS_IO], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spiq_sd0_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spid_sd1_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spihd_sd2_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_spiwp_sd3_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_cs_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.flash_clk_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_cs_io], FUN_DRV_V, 3, FUN_DRV_S);
SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[psram_io.psram_clk_io], FUN_DRV_V, 3, FUN_DRV_S);
}
if (PSRAM_IS_64MBIT(s_psram_id)) {
// For this psram, we don't need any extra clock cycles after cs get back to high level
s_clk_mode = PSRAM_CLK_MODE_NORM;
gpio_matrix_out(PSRAM_INTERNAL_IO_28, SIG_GPIO_OUT_IDX, 0, 0);
gpio_matrix_out(PSRAM_INTERNAL_IO_29, SIG_GPIO_OUT_IDX, 0, 0);
gpio_matrix_out(PSRAM_CLK_IO, SPICLK_OUT_IDX, 0, 0);
} else if (PSRAM_IS_32MBIT_VER0(s_psram_id)) {
if (PSRAM_IS_32MBIT_VER0(s_psram_id)) {
s_clk_mode = PSRAM_CLK_MODE_DCLK;
if (mode == PSRAM_CACHE_F80M_S80M) {
/* note: If the third mode(80Mhz+80Mhz) is enabled for 32MBit 1V8 psram, VSPI port will be
@ -630,7 +726,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
if (!r) {
return ESP_ERR_INVALID_STATE;
}
gpio_matrix_out(PSRAM_CLK_IO, VSPICLK_OUT_IDX, 0, 0);
gpio_matrix_out(psram_io.psram_clk_io, PSRAM_CLK_SIGNAL, 0, 0);
//use spi3 clock,but use spi1 data/cs wires
//We get a solid 80MHz clock from SPI3 by setting it up, starting a transaction, waiting until it
//is in progress, then cutting the clock (but not the reset!) to that peripheral.
@ -646,7 +742,14 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
}
}
}
} else {
// For other psram, we don't need any extra clock cycles after cs get back to high level
s_clk_mode = PSRAM_CLK_MODE_NORM;
gpio_matrix_out(PSRAM_INTERNAL_IO_28, SIG_GPIO_OUT_IDX, 0, 0);
gpio_matrix_out(PSRAM_INTERNAL_IO_29, SIG_GPIO_OUT_IDX, 0, 0);
gpio_matrix_out(psram_io.psram_clk_io, SPICLK_OUT_IDX, 0, 0);
}
psram_enable_qio_mode(PSRAM_SPI_1);
psram_cache_init(mode, vaddrmode);
return ESP_OK;

View File

@ -27,8 +27,9 @@ typedef enum {
} psram_cache_mode_t;
typedef enum {
PSRAM_SIZE_32MBITS = 0,
PSRAM_SIZE_64MBITS = 1,
PSRAM_SIZE_16MBITS = 0,
PSRAM_SIZE_32MBITS = 1,
PSRAM_SIZE_64MBITS = 2,
PSRAM_SIZE_MAX,
} psram_size_t;

View File

@ -279,8 +279,7 @@ void IRAM_ATTR esp_restart_noos()
rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_200ns);
rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_200ns);
rtc_wdt_set_time(RTC_WDT_STAGE0, 1000);
rtc_wdt_enable();
rtc_wdt_protect_on();
rtc_wdt_flashboot_mode_enable();
// Reset and stall the other CPU.
// CPU must be reset before stalling, in case it was running a s32c1i

View File

@ -0,0 +1,71 @@
/*
* Note: Currently, the backtraces must still be checked manually. Therefore,
* these test cases should always pass.
* Todo: Automate the checking of backtrace addresses.
*/
#include <stdlib.h>
#include "unity.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/xtensa_api.h"
#include "esp_intr_alloc.h"
#define SW_ISR_LEVEL_1 7
#define SW_ISR_LEVEL_3 29
#define RECUR_DEPTH 3
#define ACTION_ABORT -1
#define ACTION_INT_WDT -2
// Set to (-1) for abort(), (-2) for interrupt watchdog
static int backtrace_trigger_source;
/*
* Recursive functions to generate a longer call stack. When the max specified
* recursion depth is reached, the following actions can be taken.
*/
static void __attribute__((__noinline__)) recursive_func(int recur_depth, int action)
{
if (recur_depth > 1) {
recursive_func(recur_depth - 1, action);
} else if (action >= 0) {
xt_set_intset(1 << action);
} else if (action == ACTION_ABORT) {
abort();
// Todo: abort() causes problems in GDB Stub backtrace due to being 'non returning'.
} else if (action == ACTION_INT_WDT) {
portDISABLE_INTERRUPTS();
while (1) {
;
}
}
}
static void level_three_isr (void *arg)
{
xt_set_intclear(1 << SW_ISR_LEVEL_3); //Clear interrupt
recursive_func(RECUR_DEPTH, backtrace_trigger_source); //Abort at the max recursive depth
}
static void level_one_isr(void *arg)
{
xt_set_intclear(1 << SW_ISR_LEVEL_1); //Clear interrupt
recursive_func(RECUR_DEPTH, SW_ISR_LEVEL_3); //Trigger nested interrupt max recursive depth
}
TEST_CASE("Test backtrace from abort", "[reset_reason][reset=abort,SW_CPU_RESET]")
{
//Allocate level one and three SW interrupts
esp_intr_alloc(ETS_INTERNAL_SW0_INTR_SOURCE, 0, level_one_isr, NULL, NULL); //Level 1 SW intr
esp_intr_alloc(ETS_INTERNAL_SW1_INTR_SOURCE, 0, level_three_isr, NULL, NULL); //Level 3 SW intr
backtrace_trigger_source = ACTION_ABORT;
recursive_func(RECUR_DEPTH, SW_ISR_LEVEL_1); //Trigger lvl 1 SW interrupt at max recursive depth
}
TEST_CASE("Test backtrace from interrupt watchdog timeout", "[reset_reason][reset=Interrupt wdt timeout on CPU0,SW_CPU_RESET]")
{
//Allocate level one and three SW interrupts
esp_intr_alloc(ETS_INTERNAL_SW0_INTR_SOURCE, 0, level_one_isr, NULL, NULL); //Level 1 SW intr
esp_intr_alloc(ETS_INTERNAL_SW1_INTR_SOURCE, 0, level_three_isr, NULL, NULL); //Level 3 SW intr
backtrace_trigger_source = ACTION_INT_WDT;
recursive_func(RECUR_DEPTH, SW_ISR_LEVEL_1); //Trigger lvl 1 SW interrupt at max recursive depth
}

Some files were not shown because too many files have changed in this diff Show More