From 176896a83c415d1de1a59467d770c074cc9d81d7 Mon Sep 17 00:00:00 2001 From: Shao Ling Tan <161761051+shaoltan-amazon@users.noreply.github.com> Date: Mon, 1 Jul 2024 11:21:11 -0700 Subject: [PATCH 01/10] Add test logic to Matter Casting Automation test script for commissioner-generated-passcode flow. (#34079) --- .../examples-linux-tv-casting-app.yaml | 12 +- .../tests/linux/tv_casting_test_sequences.py | 118 +++++++++++++++++- scripts/tests/run_tv_casting_test.py | 30 +++-- 3 files changed, 147 insertions(+), 13 deletions(-) diff --git a/.github/workflows/examples-linux-tv-casting-app.yaml b/.github/workflows/examples-linux-tv-casting-app.yaml index ca6d1b6ea20e5c..2797712bffa816 100644 --- a/.github/workflows/examples-linux-tv-casting-app.yaml +++ b/.github/workflows/examples-linux-tv-casting-app.yaml @@ -63,12 +63,22 @@ jobs: ./scripts/run_in_build_env.sh \ "scripts/examples/gn_build_example.sh examples/tv-casting-app/linux/ out/tv-casting-app chip_casting_simplified=true" - - name: Test casting from Linux tv-casting-app to Linux tv-app + - name: + Test casting from Linux tv-casting-app to Linux tv-app - + Commissionee Generated Passcode run: | ./scripts/run_in_build_env.sh \ "python3 ./scripts/tests/run_tv_casting_test.py" timeout-minutes: 2 # Comment this out to debug if GitHub Action times out. + - name: + Test casting from Linux tv-casting-app to Linux tv-app - + Commissioner Generated Passcode + run: | + ./scripts/run_in_build_env.sh \ + "python3 ./scripts/tests/run_tv_casting_test.py --commissioner-generated-passcode=True" + timeout-minutes: 2 # Comment this out to debug if GitHub Action times out. + - name: Uploading Size Reports uses: ./.github/actions/upload-size-reports if: ${{ !env.ACT }} diff --git a/scripts/tests/linux/tv_casting_test_sequences.py b/scripts/tests/linux/tv_casting_test_sequences.py index 3ed249ae28532f..4ac5623e511aa6 100644 --- a/scripts/tests/linux/tv_casting_test_sequences.py +++ b/scripts/tests/linux/tv_casting_test_sequences.py @@ -67,9 +67,13 @@ # Values that identify the Linux tv-app and are noted in the 'Device Configuration' in the Linux tv-app output # as well as under the 'Discovered Commissioner' details in the Linux tv-casting-app output. -VENDOR_ID = 0xFFF1 # Spec 7.20.2.1 MEI code: test vendor IDs are 0xFFF1 to 0xFFF4 -PRODUCT_ID = 0x8001 # Test product id -DEVICE_TYPE_CASTING_VIDEO_PLAYER = 0x23 # Device type library 10.3: Casting Video Player +VENDOR_ID = 0xFFF1 # 0xFFF1 = 65521; Spec 7.20.2.1 MEI code: test vendor IDs are 0xFFF1 to 0xFFF4 +PRODUCT_ID = 0x8001 # 0x8001 = 32769 = Test product id +DEVICE_TYPE_CASTING_VIDEO_PLAYER = 0x23 # 0x23 = 35 = Device type library 10.3: Casting Video Player + +# 0x457 = 1111 = Target Content Application Vendor ID for the commissioner generated passcode flow +COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID = 0x457 +COMMISSIONER_GENERATED_PASSCODE = '0x00BC_614E' # 0x00BC_614E = 12345678 = Default commissioner generated passcode # Value to verify the subscription state against in the Linux tv-casting-app output. ATTRIBUTE_CURRENT_PLAYBACK_STATE = 0x0000_0000 # Application Cluster Spec 6.10.6 Attribute ID: Current State of Playback @@ -94,7 +98,7 @@ Step(app=App.TV_CASTING_APP, output_msg=['Discovered CastingPlayer #0', f'Product ID: {PRODUCT_ID}', f'Vendor ID: {VENDOR_ID}', f'Device Type: {DEVICE_TYPE_CASTING_VIDEO_PLAYER}', 'Supports Commissioner Generated Passcode: true']), - # Send `cast request {valid_discovered_commissioner_number}\n` command to the tv-casting-app subprocess. + # Send `cast request {valid_discovered_castingplayer_number}\n` command to the tv-casting-app subprocess. Step(app=App.TV_CASTING_APP, input_cmd='cast request 0\n'), # Validate that the tv-casting-app begins the commissioning process. @@ -112,7 +116,7 @@ # Validate that we received the instructions on the tv-app output for sending the `controller ux ok` command. Step(app=App.TV_APP, output_msg=['Via Shell Enter: controller ux ok|cancel']), - # Send `controller ux ok` command to the tv-app subprocess. + # Send `controller ux ok\n` command to the tv-app subprocess. Step(app=App.TV_APP, input_cmd='controller ux ok\n'), # Validate that pairing succeeded between the tv-casting-app and the tv-app. @@ -140,6 +144,110 @@ # Signal to stop the tv-casting-app as we finished validation. Step(app=App.TV_CASTING_APP, input_cmd=STOP_APP), + # Signal to stop the tv-app as we finished validation. + Step(app=App.TV_APP, input_cmd=STOP_APP) + ] + ), + Sequence( + name='commissioner_generated_passcode_test', + steps=[ + # Signal to start the tv-app. + Step(app=App.TV_APP, input_cmd=START_APP), + + # Validate that the tv-app is up and running. + Step(app=App.TV_APP, timeout_sec=APP_MAX_START_WAIT_SEC, output_msg=['Started commissioner']), + + # Signal to start the tv-casting-app. + Step(app=App.TV_CASTING_APP, input_cmd=START_APP), + + # Validate that the server is properly initialized in the tv-casting-app output. + Step(app=App.TV_CASTING_APP, timeout_sec=APP_MAX_START_WAIT_SEC, output_msg=['Server initialization complete']), + + # Validate that there is a valid discovered casting player with {PRODUCT_ID}, {VENDOR_ID}, {DEVICE_TYPE_CASTING_VIDEO_PLAYER}, and the + # `Commissioner Generated Passcode` flag is set to true in the tv-casting-app output. + Step(app=App.TV_CASTING_APP, output_msg=['Discovered CastingPlayer #0', f'Product ID: {PRODUCT_ID}', f'Vendor ID: {VENDOR_ID}', + f'Device Type: {DEVICE_TYPE_CASTING_VIDEO_PLAYER}', 'Supports Commissioner Generated Passcode: true']), + + # Send `cast request {valid_discovered_castingplayer_number} commissioner-generated-passcode\n` command to the tv-casting-app subprocess. + Step(app=App.TV_CASTING_APP, input_cmd='cast request 0 commissioner-generated-passcode\n'), + + # Validate that the tv-casting-app begins the commissioning process. + Step(app=App.TV_CASTING_APP, output_msg=[ + 'CastingPlayer::VerifyOrEstablishConnection() calling OpenBasicCommissioningWindow()']), + + # Validate that the `IdentificationDeclaration` message sent from the tv-casting-app to the tv-app will contain the following entries: + # mCommissionerPasscode: true -> This flag instructs the commissioner to use the commissioner-generated-passcode flow for commissioning. + # mCommissionerPasscodeReady: false -> This flag indicates that the commissionee has not obtained the commissioner passcode from the user and + # thus is not ready for commissioning. + # Vendor ID: {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID} -> The initial VENDOR_ID of the casting player will be overridden to {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID}. + # Otherwise we will enter the commissionee-generated-passcode flow. + Step(app=App.TV_CASTING_APP, output_msg=['IdentificationDeclarationOptions::LogDetail()', 'IdentificationDeclarationOptions::mCommissionerPasscode: true', + 'IdentificationDeclarationOptions::mCommissionerPasscodeReady: false', 'IdentificationDeclarationOptions::TargetAppInfos list:', f'TargetAppInfo 1, Vendor ID: {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID}']), + + # Validate that we received the cast request from the tv-casting-app on the tv-app output. + Step(app=App.TV_APP, + output_msg=['------PROMPT USER: Test TV casting app is requesting permission to cast to this TV, approve?']), + + # Validate that we received the instructions on the tv-app output for sending the `controller ux ok` command. + Step(app=App.TV_APP, output_msg=['Via Shell Enter: controller ux ok|cancel']), + + # Send `controller ux ok` command to the tv-app subprocess. + Step(app=App.TV_APP, input_cmd='controller ux ok\n'), + + # Validate that the tv-app sent a message to the tv-casting-app indicating that the tv-app is now displaying the passcode to the user. + Step(app=App.TV_APP, output_msg=['Commissioner Declaration Start', + 'commissioner passcode: true', 'Commissioner Declaration End']), + + # Validate that we received the cast request with the casting passcode on the tv-app output. + Step(app=App.TV_APP, output_msg=[ + f'------PROMPT USER: Test TV casting app is requesting permission to cast to this TV. Casting passcode: [{COMMISSIONER_GENERATED_PASSCODE}].']), + + # Validate that the tv-casting-app received the message from the tv-app indicating that the tv-app is now displaying the passcode to the user. + Step(app=App.TV_CASTING_APP, output_msg=['Commissioner Declaration Start', + 'commissioner passcode: true', 'Commissioner Declaration End']), + + # Validate that the user is prompted to input passcode from the tv-app on the tv-casting-app output. + Step(app=App.TV_CASTING_APP, output_msg=['Awaiting user input', 'Input the Commissioner-Generated passcode displayed on the CastingPlayer UX.', + f'cast setcommissionerpasscode {int(COMMISSIONER_GENERATED_PASSCODE, 16)}', 'Awaiting user input']), + + # Send `cast setcommissionerpasscode {COMMISSIONER_GENERATED_PASSCODE}\n` to the tv-casting-app subprocess. + Step(app=App.TV_CASTING_APP, input_cmd=f'cast setcommissionerpasscode {int(COMMISSIONER_GENERATED_PASSCODE, 16)}\n'), + + # Validate the commissioner passcode that the user entered on the tv-casting-app output. + Step(app=App.TV_CASTING_APP, output_msg=[ + f'CommandHandler() setcommissionerpasscode user entered passcode: {int(COMMISSIONER_GENERATED_PASSCODE, 16)}']), + + # Validate that the `IdentificationDeclaration` message sent from the tv-casting-app to the tv-app will contain the following entries: + # mCommissionerPasscode: true -> This flag instructs the commissioner to use the commissioner-generated-passcode flow for commissioning. + # mCommissionerPasscodeReady: true -> This flag indicates that the commissionee has obtained the commissioner passcode from the user and + # thus is ready for commissioning. + # Vendor ID: {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID} -> The initial VENDOR_ID of the casting player will be overridden to {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID}. + # Otherwise we will enter the commissionee-generated-passcode flow. + Step(app=App.TV_CASTING_APP, output_msg=['IdentificationDeclarationOptions::LogDetail()', 'IdentificationDeclarationOptions::mCommissionerPasscode: true', + 'IdentificationDeclarationOptions::mCommissionerPasscodeReady: true', 'IdentificationDeclarationOptions::TargetAppInfos list:', f'TargetAppInfo 1, Vendor ID: {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID}']), + + # Validate that pairing succeeded between the tv-casting-app and the tv-app. + Step(app=App.TV_APP, output_msg=['Secure Pairing Success']), + + # Validate that the connection succeeded in the tv-casting-app output. + Step(app=App.TV_CASTING_APP, output_msg=['Successfully connected to CastingPlayer']), + + # Validate that commissioning succeeded in the tv-app output. + Step(app=App.TV_APP, output_msg=['------PROMPT USER: commissioning success']), + + # Validate that we are able to subscribe to the media playback cluster by reading the CurrentState value and that it matches {ATTRIBUTE_CURRENT_PLAYBACK_STATE}. + Step(app=App.TV_CASTING_APP, output_msg=[f'Read CurrentState value: {ATTRIBUTE_CURRENT_PLAYBACK_STATE}']), + + # Validate the LaunchURL in the tv-app output. + Step(app=App.TV_APP, + output_msg=['ContentLauncherManager::HandleLaunchUrl TEST CASE ContentURL=https://www.test.com/videoid DisplayString=Test video']), + + # Validate the LaunchURL in the tv-casting-app output. + Step(app=App.TV_CASTING_APP, output_msg=['LaunchURL Success with response.data: exampleData']), + + # Signal to stop the tv-casting-app as we finished validation. + Step(app=App.TV_CASTING_APP, input_cmd=STOP_APP), + # Signal to stop the tv-app as we finished validation. Step(app=App.TV_APP, input_cmd=STOP_APP) ] diff --git a/scripts/tests/run_tv_casting_test.py b/scripts/tests/run_tv_casting_test.py index 13b003eed67e66..c5cc34dd052eb3 100644 --- a/scripts/tests/run_tv_casting_test.py +++ b/scripts/tests/run_tv_casting_test.py @@ -270,12 +270,26 @@ def run_test_sequence_steps( @click.command() @click.option('--tv-app-rel-path', type=str, default='out/tv-app/chip-tv-app', help='Path to the Linux tv-app executable.') @click.option('--tv-casting-app-rel-path', type=str, default='out/tv-casting-app/chip-tv-casting-app', help='Path to the Linux tv-casting-app executable.') -def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path): +@click.option('--commissioner-generated-passcode', type=bool, default=False, help='Enable the commissioner generated passcode test flow.') +def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path, commissioner_generated_passcode): """Test if the casting experience between the Linux tv-casting-app and the Linux tv-app continues to work. - Default paths for the executables are provided but can be overridden via command line arguments. - For example: python3 run_tv_casting_test.py --tv-app-rel-path=path/to/tv-app - --tv-casting-app-rel-path=path/to/tv-casting-app + By default, it uses the provided executable paths and the commissionee generated passcode flow as the test sequence. + + Example usages: + 1. Use default paths and test sequence: + python3 run_tv_casting_test.py + + 2. Use custom executable paths and default test sequence: + python3 run_tv_casting_test.py --tv-app-rel-path=path/to/tv-app --tv-casting-app-rel-path=path/to/tv-casting-app + + 3. Use default paths and a test sequence that is not the default test sequence (replace `test-sequence-name` with the actual name of the test sequence): + python3 run_tv_casting_test.py --test-sequence-name=True + + 4. Use custom executable paths and a test sequence that is not the default test sequence (replace `test-sequence-name` with the actual name of the test sequence): + python3 run_tv_casting_test.py --tv-app-rel-path=path/to/tv-app --tv-casting-app-rel-path=path/to/tv-casting-app --test-sequence-name=True + + Note: In order to enable a new test sequence, we also need to define a @click.option() entry for the test sequence. """ # Store the log files to a temporary directory. @@ -288,15 +302,17 @@ def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path): # Get all the test sequences. test_sequences = Sequence.get_test_sequences() - # Get the test sequence of interest. - test_sequence = Sequence.get_test_sequence_by_name(test_sequences, 'commissionee_generated_passcode_test') + # Get the test sequence that we are interested in validating. + test_sequence_name = 'commissionee_generated_passcode_test' + if commissioner_generated_passcode: + test_sequence_name = 'commissioner_generated_passcode_test' + test_sequence = Sequence.get_test_sequence_by_name(test_sequences, test_sequence_name) if not test_sequence: logging.error('No test sequence found by the test sequence name provided.') handle_casting_failure(None, []) # At this point, we have retrieved the test sequence of interest. - test_sequence_name = test_sequence.name test_sequence_steps = test_sequence.steps # Configure command options to disable stdout buffering during tests. From 3185ae1f8601b3199bd6a527271445c43d7e9a4f Mon Sep 17 00:00:00 2001 From: adabreuti <76965454+adabreuti@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:02:27 -0500 Subject: [PATCH 02/10] [TI] Update Example Applications and TI Documentation (#34060) * Update TI Applications with correct OTA startup handling * Update Linker command files and NV regions * Add test event trigger delegate * Fix pairing failure in TI applications * Update TI Matter documentation * Update Openthread OT-TI commit * Apply restyled updates * Update Image spelling * Apply restyled * Update workflow to perform recursive clone * Update nvocmp.c to fix formatting issue --------- Co-authored-by: Andrei Litvin --- .github/workflows/examples-cc13xx_26xx.yaml | 18 +- docs/guides/README.md | 2 +- docs/guides/darwin.md | 2 +- .../guides/images/matter_ti_overview_wifi.png | Bin 0 -> 103921 bytes docs/guides/index.md | 4 +- .../matter_cc2674_migration.md | 6 +- .../ti/matter-syscfg/getting-started.md | 62 + .../ti/matter-syscfg/images/board_view.png | Bin 0 -> 34394 bytes .../images/generated_files_ble.png | Bin 0 -> 460542 bytes .../ti/matter-syscfg/images/hardware_view.png | Bin 0 -> 14053 bytes .../ti/matter-syscfg/images/reserve-gpio.png | Bin 0 -> 43195 bytes .../images/reserve-peripheral-panel.png | Bin 0 -> 11332 bytes .../images/show_generated_files_tab.png | Bin 0 -> 15951 bytes .../ti/matter-syscfg/sysconfig-board.md | 69 + .../enabling_icd_on_ti_devices.md | 4 +- .../images/cc13x4_memmap.png | Bin .../images/factory_data_overview.png | Bin .../ti_factory_data_user_guide.md | 11 +- .../ti_openthread_library_usage.md | 59 +- docs/guides/ti/ti_matter_overview.md | 173 + docs/guides/ti/ti_platform_overview.md | 162 - docs/images/ti_logo.png | Bin 0 -> 4375 bytes .../all-clusters-app/cc13x4_26x4/BUILD.gn | 5 + .../all-clusters-app/cc13x4_26x4/README.md | 6 + .../all-clusters-app/cc13x4_26x4/args.gni | 11 +- .../all-clusters-app/cc13x4_26x4/chip.syscfg | 4 +- .../cc13x4_26x4/main/AppTask.cpp | 115 +- examples/lighting-app/cc13x4_26x4/BUILD.gn | 5 + examples/lighting-app/cc13x4_26x4/README.md | 7 +- examples/lighting-app/cc13x4_26x4/args.gni | 14 +- examples/lighting-app/cc13x4_26x4/chip.syscfg | 5 +- .../lighting-app/cc13x4_26x4/src/AppEvent.h | 1 + .../lighting-app/cc13x4_26x4/src/AppTask.cpp | 145 +- .../cc13x4_26x4/src/LightingManager.cpp | 7 + .../cc13x4_26x4/src/LightingManager.h | 2 + .../cc13x4_26x4/src/ZclCallbacks.cpp | 1 + examples/lock-app/cc13x4_26x4/BUILD.gn | 5 + examples/lock-app/cc13x4_26x4/README.md | 7 +- examples/lock-app/cc13x4_26x4/args.gni | 11 +- examples/lock-app/cc13x4_26x4/chip.syscfg | 5 +- examples/lock-app/cc13x4_26x4/src/AppTask.cpp | 148 +- .../project_include/OpenThreadConfig.h | 24 - examples/pump-app/cc13x4_26x4/BUILD.gn | 5 + examples/pump-app/cc13x4_26x4/README.md | 6 + examples/pump-app/cc13x4_26x4/args.gni | 11 +- examples/pump-app/cc13x4_26x4/chip.syscfg | 4 +- .../pump-app/cc13x4_26x4/main/AppTask.cpp | 125 +- .../cc13x4_26x4/main/include/AppEvent.h | 1 - .../pump-controller-app/cc13x4_26x4/BUILD.gn | 5 + .../pump-controller-app/cc13x4_26x4/README.md | 9 +- .../pump-controller-app/cc13x4_26x4/args.gni | 11 +- .../cc13x4_26x4/chip.syscfg | 4 +- .../cc13x4_26x4/main/AppTask.cpp | 137 +- .../cc13x4_26x4/main/include/AppEvent.h | 1 - examples/shell/cc13x4_26x4/README.md | 3 + examples/shell/cc13x4_26x4/args.gni | 11 +- examples/shell/cc13x4_26x4/chip.syscfg | 4 +- examples/shell/cc13x4_26x4/main/AppTask.cpp | 14 +- src/platform/cc13xx_26xx/BLEManagerImpl.cpp | 5 +- .../DefaultTestEventTriggerDelegate.cpp | 31 + .../DefaultTestEventTriggerDelegate.h | 36 + .../cc13xx_26xx/ThreadStackManagerImpl.cpp | 10 + src/platform/cc13xx_26xx/cc13x4_26x4/BUILD.gn | 3 + .../cc13x4_26x4/OTAImageProcessorImpl.cpp | 22 +- .../cc13x4_26x4/ThreadStackManagerImpl.h | 2 + .../cc13x4_26x4/cc13x4_cc26x4_freertos.lds | 4 +- .../cc13x4_cc26x4_freertos_factory_data.lds | 4 +- .../cc13x4_cc26x4_freertos_ota.lds | 12 +- ...c13x4_cc26x4_freertos_ota_factory_data.lds | 12 +- src/platform/cc13xx_26xx/nvocmp.c | 5201 +++++++++++++++++ third_party/openthread/ot-ti | 2 +- .../mcuboot/flash_map_backend.h | 2 +- .../mcuboot/mcuboot_config/mcuboot_config.h | 2 +- .../ti_simplelink_executable.gni | 2 +- .../ti_simplelink_sdk/ti_simplelink_sdk.gni | 4 +- 75 files changed, 6466 insertions(+), 339 deletions(-) create mode 100644 docs/guides/images/matter_ti_overview_wifi.png rename docs/guides/ti/{ => matter-migration-guide}/matter_cc2674_migration.md (96%) create mode 100644 docs/guides/ti/matter-syscfg/getting-started.md create mode 100644 docs/guides/ti/matter-syscfg/images/board_view.png create mode 100644 docs/guides/ti/matter-syscfg/images/generated_files_ble.png create mode 100644 docs/guides/ti/matter-syscfg/images/hardware_view.png create mode 100644 docs/guides/ti/matter-syscfg/images/reserve-gpio.png create mode 100644 docs/guides/ti/matter-syscfg/images/reserve-peripheral-panel.png create mode 100644 docs/guides/ti/matter-syscfg/images/show_generated_files_tab.png create mode 100644 docs/guides/ti/matter-syscfg/sysconfig-board.md rename docs/guides/ti/{ => matter-users-guide}/enabling_icd_on_ti_devices.md (92%) rename docs/guides/ti/{ => matter-users-guide}/images/cc13x4_memmap.png (100%) rename docs/guides/ti/{ => matter-users-guide}/images/factory_data_overview.png (100%) rename docs/guides/ti/{ => matter-users-guide}/ti_factory_data_user_guide.md (91%) rename docs/guides/ti/{ => matter-users-guide}/ti_openthread_library_usage.md (57%) create mode 100644 docs/guides/ti/ti_matter_overview.md delete mode 100644 docs/guides/ti/ti_platform_overview.md create mode 100644 docs/images/ti_logo.png create mode 100644 src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.cpp create mode 100644 src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.h create mode 100644 src/platform/cc13xx_26xx/nvocmp.c diff --git a/.github/workflows/examples-cc13xx_26xx.yaml b/.github/workflows/examples-cc13xx_26xx.yaml index abdc5605ada47b..d462d9f2725bbb 100644 --- a/.github/workflows/examples-cc13xx_26xx.yaml +++ b/.github/workflows/examples-cc13xx_26xx.yaml @@ -17,16 +17,19 @@ name: Build example - TI CC13XX_26XX on: push: branches-ignore: - - 'dependabot/**' + - "dependabot/**" pull_request: merge_group: concurrency: - group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} + group: + ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == + 'pull_request' && github.event.number) || (github.event_name == + 'workflow_dispatch' && github.run_number) || github.sha }} cancel-in-progress: true env: CHIP_NO_LOG_TIMESTAMPS: true - + jobs: cc13xx_26xx: name: cc13xx_26xx @@ -47,13 +50,14 @@ jobs: - name: Checkout submodules & Bootstrap uses: ./.github/actions/checkout-submodules-and-bootstrap with: - platform: cc13xx_26xx + platform: cc13xx_26xx + extra-submodule-parameters: " --recursive" - name: Set up environment for size reports uses: ./.github/actions/setup-size-reports if: ${{ !env.ACT }} with: - gh-context: ${{ toJson(github) }} - + gh-context: ${{ toJson(github) }} + - name: Build examples run: | scripts/run_in_build_env.sh "\ @@ -103,4 +107,4 @@ jobs: uses: ./.github/actions/upload-size-reports if: ${{ !env.ACT }} with: - platform-name: cc13x4_26x4 + platform-name: cc13x4_26x4 diff --git a/docs/guides/README.md b/docs/guides/README.md index e9a42a15861648..a00cc83e280c91 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -24,7 +24,7 @@ - [Silicon Labs - Software Update](./silabs_efr32_software_update.md) - [Silicon Labs - CLI Guide](./silabs_cli_guide.md) - [STMicroelectronics (STM32)](./stm32_getting_started_guide.md) -- [TI - Platform Overview](./ti/ti_platform_overview.md) +- [TI - Platform Overview](./ti/ti_matter_overview.md) - [Open IoT SDK - Platform Overview](./openiotsdk_platform_overview.md) - [Open IoT SDK - Examples](./openiotsdk_examples.md) - [Open IoT SDK - Unit Tests](./openiotsdk_unit_tests.md) diff --git a/docs/guides/darwin.md b/docs/guides/darwin.md index 4a9a8da939952e..2a84067da92ed0 100644 --- a/docs/guides/darwin.md +++ b/docs/guides/darwin.md @@ -267,7 +267,7 @@ Example: - [Silicon Labs](./silabs_getting_started.md) - [Simulated Linux](./simulated_device_linux.md) - [Telink](/examples/lighting-app/telink/README.md) -- [TI Platform](./ti/ti_platform_overview.md) +- [TI Platform](./ti/ti_matter_overview.md) - [TI All Clusters](/examples/all-clusters-app/cc13x4_26x4/README.md) - [Tizen](/examples/lighting-app/tizen/README.md) diff --git a/docs/guides/images/matter_ti_overview_wifi.png b/docs/guides/images/matter_ti_overview_wifi.png new file mode 100644 index 0000000000000000000000000000000000000000..4d73a30db7ff99bcfbb7ff67a80ccb1042d269e2 GIT binary patch literal 103921 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%0A3tOg*R{#qGw`9TYoL^@xa%j1A2h%rwP=un8P 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 HPRITe8}YsH literal 0 HcmV?d00001 diff --git a/docs/guides/index.md b/docs/guides/index.md index 7ec0ec61a3cc69..8f747ab27e684f 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -11,7 +11,7 @@ and features. * esp32/README nxp/README -ti/ti_platform_overview +ti/ti_matter_overview ``` ## Build Guides @@ -40,7 +40,7 @@ ti/ti_platform_overview - [Silicon Labs - Getting Started](./silabs_getting_started.md) - [Silicon Labs - Software Update](./silabs_efr32_software_update.md) - [Silicon Labs - CLI Guide](./silabs_cli_guide.md) -- [TI - Platform Overview](./ti/ti_platform_overview.md) +- [TI - Platform Overview](./ti/ti_matter_overview.md) ## Tool Guides diff --git a/docs/guides/ti/matter_cc2674_migration.md b/docs/guides/ti/matter-migration-guide/matter_cc2674_migration.md similarity index 96% rename from docs/guides/ti/matter_cc2674_migration.md rename to docs/guides/ti/matter-migration-guide/matter_cc2674_migration.md index 994954d6ae7a53..a6081d9c9a73de 100644 --- a/docs/guides/ti/matter_cc2674_migration.md +++ b/docs/guides/ti/matter-migration-guide/matter_cc2674_migration.md @@ -50,9 +50,9 @@ The GPIO pin values for SPI will need to be adjusted based on your design. 4. Select _Board_ as _None_ and _Device_ as _`CC2674P10RGZ`_, Unselect _`Lock PinMux`_, and click _Confirm_. 5. To fix errors, make the following module changes: - - _RF Design_ and _RF Stacks -> BLE -> Radio_: click on _accepting the - current value_, which should be _`LP_CC2674P10_RGZ`_ in the drop down menu - for _Based On RF Design_ + - _RF Design_ and _RF Stacks -> Bluetooth LE -> Radio_: click on _accepting + the current value_, which should be _`LP_CC2674P10_RGZ`_ in the drop down + menu for _Based On RF Design_ - _TI DEVICES -> Device Configuration_: Clear _`XOSC Cap Array Modification`_ - _TI DRIVERS -> RF_: Set _Global Event Mask_ as _None_ and _No. of Antenna diff --git a/docs/guides/ti/matter-syscfg/getting-started.md b/docs/guides/ti/matter-syscfg/getting-started.md new file mode 100644 index 00000000000000..af90b79c7c87f6 --- /dev/null +++ b/docs/guides/ti/matter-syscfg/getting-started.md @@ -0,0 +1,62 @@ +# Get started with SysConfig + +System Configuration Tool (SysConfig) is a graphical interface for configuring +your project. Configuration files, C source files and header files are generated +based on the parameters configured in the SysConfig dashboard. + +SysConfig should be used as a standalone tool for script-based builds (such as +for Matter). + +The document will help for getting started in tailoring the `syscfg` file to +your application needs. + +## Using Stand-alone SysConfig + +You can find the standalone SysConfig tool on the +[SysConfig Standalone Installer Download Page](https://www.ti.com/tool/SYSCONFIG). + +The location of the Matter `syscfg` file is located here: +`/examples//cc13x4_26x4/chip.syscfg` For example, on the github web: +`https://github.com/project-chip/connectedhomeip/blob/master/examples/lock-app/cc13x4_26x4/chip.syscfg` +The local file in your cloned repository should be used. + +This file is used by Matter build scripts, when it invokes SysConfig CLI. In +order to edit the file for your custom application configurations, you'll need +to open the file with the SysConfig GUI. Before doing so, you should add the +following line above the `/* Modules */` comment: + +``` +// @cliArgs --product /.metadata/product.json --board /ti/boards/LP_EM_CC1354P10_6 --rtos freertos +``` + +As an example, after adding the necessary ``, it would look like: + +``` +// @cliArgs --product /home/Documents/repos/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/.metadata/product.json --board /ti/boards/LP_EM_CC1354P10_6 --rtos freertos +``` + +If the file is not found, then you may need to first initialize the submodules: + +``` +git submodule update --init +``` + +Now you can open the file in SysConfig GUI. Once you are done, remove the +`@cliArgs` line then save the file. Now the Matter build scripts will use the +updated `.syscfg` file. + +## Viewing SysConfig Output + +To preview the code to be generated reference the `Generated Files` image, the +button at the top of the `Configuration` pane you will find a list of Generated +Files. After selecting a file you will be able, in real-time, to identify how +the changes in the GUI affect the generated files. This will help you review the +relationship between the GUI and the code. + +

+ Generated Files +
Generated Files
+
+ +Whenever you re-build the project, SysConfig will re-generate the files. Because +of this, any changes made directly in the generated files will be overwritten. diff --git a/docs/guides/ti/matter-syscfg/images/board_view.png b/docs/guides/ti/matter-syscfg/images/board_view.png new file mode 100644 index 0000000000000000000000000000000000000000..4067a24495f84348478d950ba52db18460531178 GIT binary patch literal 34394 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 literal 0 HcmV?d00001 diff --git a/docs/guides/ti/matter-syscfg/images/generated_files_ble.png b/docs/guides/ti/matter-syscfg/images/generated_files_ble.png new file mode 100644 index 0000000000000000000000000000000000000000..39cf576cac92b4a87262f37ad5ec3875d55d8340 GIT binary patch literal 460542 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%0D0Vx;dWLe#{(oGUzrJ`XuNDkE%5|9*qh4>%*jVS( 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 z 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%0A!zloUA_w!2y!O#F!)9nU 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

  • dF7Zoy&)3>oqEsR`ALAr$4tUD=()Mx`m=b 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 literal 0 HcmV?d00001 diff --git a/docs/guides/ti/matter-syscfg/images/show_generated_files_tab.png b/docs/guides/ti/matter-syscfg/images/show_generated_files_tab.png new file mode 100644 index 0000000000000000000000000000000000000000..19f09e419f43365480df62b27f0ac6368af9dd2b GIT binary patch literal 15951 zcmchebx>U0*5+}y#u|b*B)A86Xxv?b1b2r3!M$;p;2PZBg9RtJy9SrwI=t___p7OI zW@=`tzWe>r)qPIwI;VP{v-kR~XFV%SNkI}F* znrRQ$x$hR6S=Giod5IJ@EiYr+*1NnIq(&GWVZzPE@SE66u*GI?vS91%a!OU@g%yQ0 zMOs*=9fO8n8B7JmcPXj@4he1}NbN8LMK`UNuH*KefDj2QhRpxTSAYL-Wna))Fyz}G zp<8dVt;%dTEC4{S$nMZL3<9Y{g$;s0J{tOA0pdQOVSzwXJ86Nx$I5v26u>jCE3Wf; zhZ#MMD^`A5K(3D;2mfeR>c)+{jmxX-eMj)+%a=>9COesdq>t-Heo_$y2ba4eP7YGc zPqS4%*L74NP##})BI4`IZCBNv$nELsG6t5Vspa8f9d%$J1hQk(?0%8Ak`wzq8$C~! zUTRfC#a&7sF9Z<)kS^elbrKmyq@~vJLXkxQMD)XCDikqMfItBms49X|Jd#7>jM8tyClDG6eKIt!{i^ z3c<#K8C+m^>& zkdzd5+iRvn0@G1EiO3|@J%`jxPmiq(oS=Xy@Nj=Rb?Zvl{{)&{J;bWnDcY)F?g2E> zz#()fFidtEnsDp;u9DG`o#I|h6>mj=`w%=L+8piS+GAnzISh92Mfjb%q?M1TK~CCs z3G-WdfD&d&qdXVtGqSKk?WhKEWIM=OhX2lBnC96fqa=H^iyc&Z|HGPy(X%hz(TJYn zwo%;sm;Pv+s*%Jwjry-%@i;A7bhZYSvJx*{GrR8w2XaWwWf?+MFG|~)C(|Ny!^?53 zg2B8P%YSM;$RNer5B;z^Uwe8FH9{c=ZMvysWQfePd^X&Ww&U8UO$X(XQdSFoWW}8sI4#oIo|djyOyr`0mddM`5tD z#EfdhD-dhfR^eBlNbj3q>s|`L1*9V2pR-ge!;3*wq6zchwj3nkl zz;_I(u-Srn7W+_Q3k;)+ov7lPI3^fdS+{{Rkjd){e_!(II<<~Artu%28XO^>E8=T0 z99XjPz}_Nz<5+Cvftg%{N&7xUq343}RWB7cm2Gj=6`m1UdZii?sVt7X z8oNF;s$Q58JP-J80PjJmMX#533rm`!7wR8iMB*vEYg#k+t5rweW)|sT#%F3y7rG-W z&6t@JT>6{!=Bm9VK|zn#{FSQ4?^FVF z!_~p%(^$^@Bb55qxE7=5m?m@Tr|p^d8VC$)W}YHR-*0r))Y<2@k3Ll4O?xpn)P7SX z)FLQwF_hL5Fg1nO;!v-!o<%2Jm&dKSIWiki4oOv3iNXjWw66BtH(<3+#8`hh;gQ4e z#cOFgv}6OdTKZhzLz1ytk~S$EFRnrj|0wKas{-q#FgvmVj~LcO=dQocFuZS|36_^t z|5Txv$Y%ySkRdi$pI}c|9f?idTpS<@A$ix74CTDMZxMH>;}Je99T*4YTRheaKRm~I z;aEL3_tLWvN32Wt9^Dpg$4e`D!s&EtTYc==5zDbJT+aP&QB0r%8ayQtZP zjWG8H#847E5ZSywcoBBcXI(&y+BNXE6=o5LldVNBH|Gy>&q{X~#Fq0Ik35_IcmXksoMnD2G$kK=S7cDVke`aPT5bMEk2X@j8vr=xjy*QWv2z z{f#|OTJVm1lM$94Vz%U7kEuMr#y(x{XP%^pJHm+A_lQ@>$B}wL4OS%Mgcm1<0vTUx zP$P=-k64V!$HaD4TC&$)WJl~g+y`CG)4E90#jL8ojGII{IQK#(;1{%ZW9oN)uDd$8 z-*FUloCan7QcQll30&tioQg*xSaLmK|2&TP4T+;lVgc69;ZLT&BFT0&w-O1Jy`2`E zMx|@_K5JJ$(kn~308votA_$iWk_;L3%i%(xPUe`#mUcIpV(~HvShz-B<%T0QTxitX6sA=(kCS^tTYGLIpZJ z=QZ%lV5jJ+*I@kEfrJB?Jej_LDc}a!fpC2|OWgMNm=gexLI*6g)?BW1u#C-%He|9V-i0_ZU~1ICmgxxX;nnw4UP=- zgJho~NcKa1kN)JK>y!eQUxQvmQ6lF^Sz7wBVfS##)qRcWI>AA+l&z=ue+_48tw65`n%L0hpRtmSye$ee`sE~ z+r4MeYlV>gD>&Igy*J9AB=cRp;n;Hz&s#$TjBIakX_a&UFfjWmsNW+9dMDOK{GxK- zJ?%A&PQ;lc$q7V|;_pd|^tT|HXQ8wf19{<(Dl=_;!C(m*>&ZB2Q*yZm2_icFLhR8y zgUZZQ!#}#a|4~?^>tWo-S^8pm(u2KE(G<&2t*d+#2GNO4NC-^P|5`F8t+SspC;d}+ zj=WF1qLm4+cmadz*Skpq2}(2amLc&K0BTF zvz}dNa+3pU9HD8ok8wuYQN>m&_G4-zdGYGj`^*HjmOq6;e(UI7BFlISR6m$~BFf>HJjZF&`mqfuF%ETid58RB#DQ1a4Z4}qp z2*@D>uv9`MOCLr;8$wk9MBmWzb=Tu{2%P^YJ1R4-LESFW*Z7?8yW3qM-3d0}H>et8 zQ8fCN%zEPhI84!_qVeDEUk-01JV6u~_l}Nf;V9}7J2cclZ0Sg0;r_|Q1C8p=7Uu(F zm|t##Bc`*U3jWXag7tX^|Mk4<1wD>eSKipx5>E) z4+~S?w-Y?F&trcB;oq(2zNT+f%=O>G#{c*AU*L=&B}OtlGF}{fLnrcd$tcBFh~H4m z8-4lCwX?3xfjC`ID^z(TVZyDSx4nM<>$>9Mla;dLO!+vDUe`E)yy(X0=F*l%E#fX0 zi`iyOOd(UJlaUEzKA_NEz2B^Jx+3Ft(v!a05lciAT=y&3D9qfqA;d0Bl@Rj9Iq*}2 zDk!{CA}TzWaEnEUmtV7irzRcD}a3_8X7qblmr~>Z8)3UR+wG-%h%JN)Ogc z7>5oKYLA{jGYC&C*Ky5-|2|p>xk}NY#R0T10P&`_dWVp*l1fKMBBgvjVwX%I>e%7Y zR*;45I-tBwxU$`@T;$)7FK)e@toxC|SexpD3?t2;lgTj$#ZDs=gxn41$} zMfwlw5Ck``7vs%?MECAjc;ztgs(ddj%bPLp^eaSrS*h&SA_8yaMZy-$M3j7Yo+uGL zwi3>GjF86D-}UZI#BCF7oMLD;lota<>R|1A{UU*R4mbC-NO$v0j{bto^Q6O1xPV!) z^Efpi2cU~~J-7+AU%l%)mc40q;90`2jpH8k^MmS$)Ylqpg^H44`GI3!9!d%s8|!XW z$bntov2W^5Yns3^)@22W(H`Wa;|>=aAxq*8KONP3%#nCX@#hOL-@!)3{&>*<(i8H6 zRKkY$aCi$hJ_j$m?_}iarfO>*K)0>6CimTfMg6vU749>9<Eyz|vtso#74@1bFL^YRUGvyNTg z1;5YRF#JKBXc*Hhh8S(A_zk0*GU@sqiKK$I+vqhJJhi9t3_AEcKLKmch#KX?P9lsi z1_7pK$@nCR;@2zD_Pc=GP>kqR1{$F+*c|wL%`Y#=xZtNsZSFcIlAucc7Q@x0c zoRl_U+rasPdqLwQ=Q=VZgC>m!6!D45245)lS?}McM1fpI?^vFqpVeH2@yup=BA-rZ zk@Q#)^)ZaTWs>?&n^ABzY0VH|apOq+(qz7SoX*WYgax+D4C>ay5>nJ*3Cb<`L8!Bl z7(Q*mQpOxv{v&_qt~*^P*Q;4{}B=;OVybQ0b?QED2t3$kK@m`+8vU4vD?)3(`B z*lt(XMwxA7KQdl3!pec!B9%=f8ou$NV#D}46J%oGk?r^sp90$%=|J+;TpXc}KPiuA57@g{o45U z=Ey|0PG#!jzVZXmSZ-}|VQ>?doQv9s6- zhV*P(X?v4R7vLxF-06=3_fxzzXr~xKuJjdQ{q&MRN|2J3@9)iP2PC#NMTxj80IpSp zYV2K@YwPJbL#FHw`CUT ze{{=tPIQ1==;pRL;?uk7ajiV}lFGm|uKpa-)0Ev>jO^(yCa=LNYKGqcq<;!`Ba!-DnnF1+C{&C*Gb&BT7}c4%aN*q3`wue5}SH) z1)toz^R)y>d?Q|VcoQ>G>{WByitGmWrm_jYJABxXk*AT6@&F<^M^94}Ytqd{2DTsG z%?G$jxd6!?JL2QD1$hnAl^Dn|wrP(3SF&Do?(A$jpO^v-Haad~13_$cOFa zxw+8S*Vo0Bl|OSt0%rp^f&pKqxUaeSP$6v7t@CP zf6?*(JbWgRU{n-c$2&To$~y8sD`saSs}Qc>Rdk_u ziH7270M@10i{RO-3cwE>-s^Brzllo&3K ztL7$bo&QRZ?HsHfWx#P-{TYPlO>mZ#Eg-6;$}_SMab#^4J+-n=POL!d*Jh*x$yv5Z z#tEKJb~-Zl!{f_uSveKDI?^A^NjcN-j}H zM1HQYva}ZwGJTfav$%)=XG~s;FF|q2W!2vRi8%bz;+jfKr~kS&t>s8|-l0>-9T@n< zIPThpCLnW0ymsxJWQ{1S@cm&*K869QKn%o?bV5A>^*6QTglGH0UXOX~^#f!jt(>X1T`xoq=kojGc)BY5(?>S)N+rCP{sqANl;iufRA~HB=ZuZO2N{!j4-l=w(mX5(f)eLZD%6t|C7R5AyD>TK zaI<(};Z)j_drbV)(hci@ny19(3;LS=iIA)&6)W2c9J3xgyzhJ-Mser#h+(2pcI}eR z^TS${Tt!yiig55D4`Dlbf8)qJtMiG3VPql+vetUjI3AZ)_p;N*{4P-=6|(XOe>;r4JCJ8FFDKg zfr`)5aE-<^UBQQv^|nVESLbZcQ^4<=G2#zp8`YH$qD460l)SMEXY)ANP580FS^@{< z-%y4!M9(wisn#z1AcyfiII$D)B&P63aW6d-##gmWmTnhOFIM7qtc3W$7JWCPBIbtq%*X34h7X>PjRPNb z_&hTaKVS+*34|UR(w2aK#%`V`aZ=gVISHL6wHEBqV%mo#OSD`w>DrvxxoR8}cPc9M zVuzx%H#i2a1YetV^H@5TDX7nf*-EXO&;xKmcNs1zhJcFLH31v_l?pC|6}_10IXedV zK4gxoKEE}q8gveGE9KearwlX%w4;3dgOtrYpe;cCmh@20nduyP($GBDA~2EY;@&%^ zdtF_JDd0y&jQGppMtf?z!61weOD{tg#&5$vjxNZbg2$j6r1S{T>`PFs6Ph1C`?y%T z+4;EuRXdQN3SBafHwA25WtVXo!|GI0631}Ol}giFVMbyEHlGJS zdNm7|a}D4KbS{R?Rz!b=8Gr6u^$k49?=vFe0E)Z2q7^9dxQH#hE&_*KLt4v=1dq&0qH(- zaox$r4l7)Dl0-qG3~Yy{lJk!so5E5(m;6v;GgAtEes(yVnJ0%!g79jbeyJx35`IC= zfSs6|y!QTx-?>3J8TC9%Ww}kYg6O8KHygo>qSC-l%2#hwmfXtWL;=APr<)nY8z~0bQO&)G&7;% zU1lc3<7tOUy_6QNlh)+?ejb9nOcc9(ljc&L*>#PEawLsrdFB~4$PBvUJl#llAdPW@ zefX^SfPbaeiJ|-fF{pm3V?ED~H1*gH(VWZ8U1$CMevOp77mdP6a^p9+nCt#(H1;12 z{dOh(sXVp}2#Me66%F6x<(u_Ujat_<4npmC*NS*dS)JiM(efi@ZAnZz_T&$` zpQB(W%;%nkqeFNFp-KRqv7R71zx_n0@@g&$heGb`pjGaLjti60$VWh&ULM-a(Fy=) z_v8La?cPhmRv;{t6j|JX$e7o~xnC&v3kSS7<@2SBjl#FUMnMJngH7Nurn4}XSLGMJ z!_N@?nEu<-AMBk|jj-odHKVT`eWw3&hh!iGAF*5SB(&Bz8rbqHMY}9vWNOkEolrFXqXW z4@|YOqbwNs_BRQtJu=IKXBz&cZyrO7a+SI)e`sH|<=22i4>ryOT#z02A53oEjRbv( zEXPq!F+q=2_=q6d)WhOy0GF|hDs%wEO1Q~?dXaVy+!O(y{P;JbAlL4he_~2XnKKwX zqutWlTIy`Oon8MX(8}K-7XG`?^B>x*%Q%!}v6#mqVZ(&}dx$|Nyk*ghkuygUO+{-S z{wWJE+ISlAh{ehS`=L@RH04J3%#%7}DPnP?DOZV6Wx!le$6v=a>$k>lV(6)-t!ps~ z{e`s94BiGWoW#>1i9rlX2CI7ol~!xu+VN@d$^uP>HxsTb|6>`4%W}rBaD6(_icSW$ zGL;6axkN9cNSbveQdr~BW2m9BD83wU_Aps@w0}v6N%TRvLCyu$WgH)}Oy%{k^-=D$ zFxfu9Fh(#celcsJDvHIa-T%%+~$~f0FRrD>|)Edsw z3zP}z9f9}yazyE#o(C|RQeJS6%DvBCneO&#u3@ID|VC30IvGa+qZ`4B~CsoSG7xp=%u@-r%6XDk=QXfM(*Y z9OyXWe16R?zsw%;iX?t=FEx5mqgS_})&z;~fre`F%JGfD4>~sC> z89#GPO?lu*M*MB~A2KJ(-!f-frL3Of{&A00XleZRAh87&(5EDO1S2|s6_BG=f?#Af zp~TH|6I8j_ws9AWXhav2EBs(LlSp3l73zcgQvM+kPJCtui+y6PJat!Gs^=yZN(FFI zAM^9x0<;6}GHz4Y!~yt&S~l3S!D0-JFa{2wp~y>L)>u%wLokKlX|y+MoCSef&vkgY z_1N)tBUOBW`_UAWc~^4XQ=P+_`nnA;iI@u(&GyS8ZIw%FlH<$aAhE9s()OT&( z`Ads?F(U6-_^!2KmbuuJ%tcl`wF)BWF z5sZE8#Blr-`a|5SeB-n5?`?glr_vf@hNlt-f-9r+t-9ll9LZT^969PfU~e}nD=kmz zkt_9=2NloN8t8x#quM5WPr3Ytx_OV!mmAXy&c&q3@iHc8gct^vVpE*-x7+$9vNBnh z=gAh9iJBu-@l9?`y!2l%)~SmO!^Gg%mYPLQd%o6fWYjmS7nL6MaTeIuCLy5!ycAkT zsv#OuXQZ6Wr*lNGr-o^(#J?{K{9|n-e-VF!|mFj}vhQ`-{QEvqBq81N7&Bj;%-jr*}c!~n&D;&4Ee+ToKNy~ zWdf-6FPX6fr$l@*iy;WpS#!kJnGgrg=9i?M53g>(b52T1IA)9>R@voDx5p7KS@9f~ zDL|eiWqsiD;+_rePDO9Cn4!CA8;4af{UI1yCFT!sX7S4#l?80bP^!ojntNB}?D-)t z%BZ*fmcSes9TshOH$(bRe80KFifc$69(Nb@@O0jSP32n;+~u6VmMFToO_X=%Q6y2d zn5wn-R{Ja_^(eCVS^fee$SXGV>~)o>lk)5K+5O@mA2rPPT+-caJkX{l=7#e1LOo$P zvfYpL>@&%v`jH2jouoy6BHO>@L9PpJ%T}H@A4t_d1;KNx$9&t$7x!{=e*8)o|5vfO z`R3j;OLor65z%0;B2y7@4N!cS)j^Xa1I<@owmhMabb4k}W4Nv!nUumAp_FpI7=JXW zDLSM0?mlGvFWR52>lxSl7;M7o$;R;>hT>7%4nIC}3}%1H>J(?fMolL{vLQlq;{qcG z7JE@tzu%P0E^T>%(M)7&kOyOIx07f;%oDroM>L zCGVA94fH>xJfM?eANu*fq&(dHglZzhHm)qWBu61ot*nkWD8jDlj(Vo@dyYkcL00q_ zt@Fg(KnbnDQ^2z!22y|`nQNSdKSAES@kIyUd1O`n2~@kzF-%t+V{kl%AnOspg@Lqt ziZ#*`;W5NsVr3?IiEc)H`G@pnqytAY%sT3E!PysC9Dpk$wPF^y%jcQb({Cb*ZnY8F-i;^* zPeg1}%N+cK=;`>?h5LogpYjMi!)ER0lE;eGiWhSK2-;ZDzmx7FPOT@~y;bZXLc;`E zA^t7PwN}Ib8!F8$w7!@H?d`gml%Txv;n`XBOlzXo0>;1GokBF?|K`f})CxRKe8OC} zu?O}RX6XooH&aKAn1jBqhz;u`83HPt>0fMTu0`2lis*audxFiEn2K&b`+ao&UAMY0 zW6gk~A1S(GKNAe*lIeuBbyxIDw=}1-=WixY^qA`V*nVVFC^1!64j2=!@{l5yAIKA` z6h9Sj@LCOzUDzS$0I(PX;=4-KkMQtX!XW6E$@Aatf{K4N=?7WIU8{@$cf-5J{FY_4 zjiL;M>uw8gvWFo2fFOCvzZ@l13^O@Hzw%HG{XQDExWHFFKs)U4iE$-3Bh4iy<;tbK zITXpaV$B#+`hUpkoqTT*f=Nfk@2x7*nWM2QyCy)5ZS3=d-K>#f)I1zrHU=a+AjjAa zCd?1{P$O~J3x#XG(uxPddcjb}UJvbWk*+5LwA1Av9xICF7pN9Domxy9(7mghMn#DS z4=&LoJHgvh%k9Yd$<%L2jw@vNV>gIVs2QD<-q}G)U%HyOXXH)tly6miqp;#H;@5hA z*P1KJDN7joM#_?SW9}HGIOoEG&0}x$v0;3n*f6~!JO9F79nGcNP@;G9&)}JkCg7Iw ze8}Gw?H_nX>szk>ENRy&-zj68*$;J(oP}Qt(kbIF5jRP;bDypz4PW;1oO^O%9=ZW7 zSSTEKKfHlU@_S&UyY((YAJJ^)b8P4Vy-My1!QU!iUODmfLV+H)i->*%FHg%Z8xy`Z zL^9O^nF>E5*w*FKtWVO)f)zwJdD5jO(LzQpw-Aa2BoD6sU+`SeF6_BvPRFO%)7nzij3uw-`QSrosT zP0prwsi$tS(hbV!ZU3BqH`Mae*mC9jlnUx6WRni^wP_E+ExFcc1ps-d;7IqOU4HDN z5$?D|RR4K?+xeH=W~rAY*guZMo-@`}yA!NWtBy!snMbh+EkFZ|ZvpYaZ>E92ac|ei z`ag=$M{nB}oPpiC|LEaA3fQ;Me=}TuPW zz2yQKM^bM59))P0;2%RW{Vgw6NFUIYN8&xv?h*`qO?*1ZcF{ptZpl9!N2vxG|HOAd z9)4o5PO<(~cqfjbe3}-EGQc>jzv{M5tG6ydL2;`HKo^KW1dF$ z9eP>DGz>m>8FI52W^%t3y)Ow$@w@1BjP)Ua-FkT84ZbY_JrbA`62nZzA|x!yOpKyK zI%ORXWn45!`Xlb1$5KST+W_2!;W(}8=@e#CW=PYc1Gfm`1$IWMVAzzE;{^#DDe|w7 zE$Itr|Gxyozv%Vl(%R)Vsykg3onUQ?&rmeF`SjN{$^JzAZ2Yitf|#wOCCT|o5hRPtQ$JDU1Zp@ zf@(~PDJcR8buTKG1sI?qb`au8ysbmTsojg+L2Wz~U_)!m9d!Ypm+8aFvU=+E>)T!z zQ_P~dSzRlmYVz5uZ$0DTnMz#VtM))r%A#cq{CC zC-sPvt#%ui?~h~VaolHmNVmg)uH2e6<67ra9oAh^$1+V!sPK_U?16{U zX?>pJ)WfyyUrK2~K5!lvQDAfcqt`{D-7!$Cn%^8x6mf+4xRzJkuNff-WZVo-Yx!w| z!qxBuS3b;u)-|g)bfX<9*on9|C8-1JDaWO|KJ+YMy1FkH#@=>?+|95<+d)AmGL5~V z7~9;t>C&m2Q~?1tWQc5Pk10Y!L=o+G1^)6bTJ$`WfX(`%V4k`O!Ng^MYr6dY(e6lb zZBrc&XIx5$Ck*hAoD+E-aW#iNVY~r5bl7uiXdOdM!zz#3i~1{+EB+`UbAX~=I7O!v zimRl2H-?-SHL@|+PVQBFV)#rUL_=hyk(=8a5Hm<#@`;AD#rCR2mjrgPkw71x8jZBv zC;VE$V(l(go8i*@x-`xo@;g1+D~>by=~vAp7F_n8n?S|yNxe)U2vcH|*wiTYzTW;cM`5YskNq*n#g;(b0`=|K2CDBvU z1)K5Ck8Br6&*17>UC$yxvFdtN-Lx_FzF~psnH9Vepojg~T>1jCI@DPaQC)58EqRei zFfQX^*3rAUk-0;2l&qdHZTb~dpLLqbkZtX}ANNNanfUP<+>_No(?l97Zetz`+}h)h zdUjOY&ZpSNx*K}2j@(rWosg`m$Lf2Q!xd`^ezc~C}Rxb zj6?%gY({CNSA389^O?VRJuGi;EH+Oc)0#@Qy4b(`1}&%~ zPI+*lrImx$FQbsn)ODqRrdoQ#xbf=@z)=4_;Pz;}cohZ~uwfX=b({Qo5EheW2f*sa#Mq|;S{779-n|BC`a+9|sfDro<1tW=n`)JGsgrEx;sA|+D<6rdX{U$5 z8xpkCTe5J+C3NSxbknSvd!rL`k|ia1yi+(>+sM20tnA>ouIg;)<4n0j0qsulH2YX{ zV>%hYQ%Ib+tH!itppRMwzbXHdTbDEoL+odnR_h1cTpzCOMS4_*hCKO=oKOW`p9_I| z{-(kK_{tQ%rz}q6?N$c0!6K8llqT=tw-fx7F}3l*m+L6&P4BV_+o_vFY+ez+h2Gm5 zX(YieGM_0N@Y%7jes+!4*78Et4(}8?Df-+g{gCiz1}8qO%yd#wb$qxoyAk%Dbhg!- z!=dMIr@(yF(pPLu0qpP%{IfmiU$oF#hW4Tx!&L56$3MGI=TC1OFH!qLZ?nLOS1#&a zbZeb9!c*I)PV`%k0sNzD&T`r{Ep}o6c4K~@KfM@F5*cL!4@Mbe*EGqImMcZmG;VMo zuO!axXa7_&buaUE3F|kcb~zx~pLId*eYQ83D!4uUoP-gJw{WrTUi?6KfEjXVj(A*WVgmPU!9F$<3&V zU+dAU1XdWR9`4935&`OyFK@~=+3nY`+wHEoUeiap$k?_jC+NVGyQhfH%JUNvh+9D85-c4Ct#q-Z6$S@j%%*YU>@+mbdv} z&v z85>Ju`9jA*PHp~~aGm-=l~jqX&8Zcjd%>J3v{z1^exdz89hF$k-#VvS+u{8(t&#m~6mJXR)?J1wcbs=PX7JdliG?s}01ZuTCjr>a|e>VCr zZhuR^ycHfE8JXn)fey=c^(uT#x@_IX|I*0wmcxCO!XXelq<>>$9ykF+)hbT8{brD; zT0%)39WLi#e`kj*F5?d=#yNC>HoB)H?XJ*mkHB8p*qgh=%`DMx`SiEbAq@1+PHto% zhq#K?8DQ3)jT+I)1W-1gYk}D@0%*KutErXr@3rrxsgJaq+JVyWC;ZuLj(Lt zC+%=4-;(#+QGP&`&+Ww;Z_h7)SKd!6JOS|9%fRrBS4+?7Ir5)H>k*ua0Pl3x5j)1L zM{59az&zygZ=Xe8KNh=8xo%eYLaIG0t+r*qO_~k`3^nZhZ=~rxU8dw0M@r)Ck;L01 ze6#KzO%-K|SrUcrfLqtpbfyLqr|MAwlDM$@V+6`P1KoWjtO&r6Jy~}-5H`1iau}lP zND=KR2*;#C7N1G#I^R@N&mTJ3#w|LlXAbSeF0qp+|{gr zMgBG!TH%zw5V4%PRwW<5s$zE}AzPGY5DKlEZf^~pDT-ASgXlT8J=~KUikv0^8Te}C=nmRwynhMr ze$ZWnkW7iGQX4`tA5C4Bh6U8~W@K7y$>6wHC1 z#~7ggSa~}{2mACg5^(3nu0#<$n545~uM_brKX4=eiWphFSRJvL@vSfF^Z=>@m&r)a z__UJ9r>}|QYZWchkXF>&Ylw?3ki;IXc&lF^+WLFYfTzcLtP_uo#+Z+q0LDB4WsNkHIE)qrDF$co57a9fLJ@vtNM=?Hdw5 z1Kt*T^#688eCt8R{pU{Cs)72}i)=^wZ?jJQqvOCy^`*ep!=r^)5)95vDl04Fo##Bt tuHRh;Q-ku3db+|C{*O8ly5B2iX(W_aG6~t%TfaAyw73GeQuK4c{{YR7*k%9# literal 0 HcmV?d00001 diff --git a/docs/guides/ti/matter-syscfg/sysconfig-board.md b/docs/guides/ti/matter-syscfg/sysconfig-board.md new file mode 100644 index 00000000000000..371b5e00b5ea3c --- /dev/null +++ b/docs/guides/ti/matter-syscfg/sysconfig-board.md @@ -0,0 +1,69 @@ +# Configure The Board Files with SysConfig + +The board view shows you what pins are available on your board, and what +peripherals are assigned to what pins. Hover over each pin for more information. + +
    + +
    + +Enabled and configured peripherals are displayed with green symbols. To add a +new peripheral, press the plus sign next to the peripheral type. The \"Show +generated files\" tab lets you see the files generated based on SysConfig. +Generated files are dynamically updated every time you make a change in +SysConfig. When you build your project, the generated files are exported into +the output folder of your project. + +
    + +
    + +## Reserve Peripherals + +Certain use cases may require preventing SysConfig from generating the +configuration of specific peripherals. + +Examples of use cases requiring to reserve peripherals are: + +- dynamic re-configuration of a peripheral +- leveraging the Sensor Controller (on devices enabling it) +- already handling certain peripherals configuration +- with hardware constraints preventing to use certain peripherals (typically + `GPIOs`) +- peripherals reserved for future use + +Below are the steps required to utilize the Reserve Peripherals feature. + +1. Open the `.syscfg` file using the SysConfig GUI + +2. Open the panel \"Reserve Peripherals\" + +
    + +
    + +3. Reserve the resources + + Reserve a peripheral using SysConfig. This image shows how to reserve `DIO` + 15 + +
    + +
    + +SysConfig ensures no resource conflict occurs. In case no solution can be found, +an error is raised. + +## Hardware View + +The Hardware view may be used to add software modules for supporting hardware +resources on EVMs or LaunchPads. The same capability could be done in the +Software view by adding a Hardware. However the Hardware view provides a +hardware-first perspective to show which software could be used with hardware +resources. + +Sysconfig Hardware View: + +
    + +
    diff --git a/docs/guides/ti/enabling_icd_on_ti_devices.md b/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md similarity index 92% rename from docs/guides/ti/enabling_icd_on_ti_devices.md rename to docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md index 7e10ceb0c11ee0..2603343ac0c26c 100644 --- a/docs/guides/ti/enabling_icd_on_ti_devices.md +++ b/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md @@ -1,4 +1,4 @@ -# Configuring Intermittently Connected Devices on TI CC13x4 Platforms +# Configuring Intermittently Connected Devices on TI SimpleLink CC13x4_CC26x4 Platforms ## Overview @@ -6,7 +6,7 @@ Intermittently Connected Devices are devices in a network that do not always need to be active. Matter has defined a cluster that helps capture this behavior; this configuration is ideal for devices that need to operate with low power consumption or do not have a need to always be on the network. Matter -examples on the TI CC13x4 platform can be configured to act as ICDs. +examples on the TI CC13x4_CC26x4 platform can be configured to act as ICDs. ## Platform Code Changes diff --git a/docs/guides/ti/images/cc13x4_memmap.png b/docs/guides/ti/matter-users-guide/images/cc13x4_memmap.png similarity index 100% rename from docs/guides/ti/images/cc13x4_memmap.png rename to docs/guides/ti/matter-users-guide/images/cc13x4_memmap.png diff --git a/docs/guides/ti/images/factory_data_overview.png b/docs/guides/ti/matter-users-guide/images/factory_data_overview.png similarity index 100% rename from docs/guides/ti/images/factory_data_overview.png rename to docs/guides/ti/matter-users-guide/images/factory_data_overview.png diff --git a/docs/guides/ti/ti_factory_data_user_guide.md b/docs/guides/ti/matter-users-guide/ti_factory_data_user_guide.md similarity index 91% rename from docs/guides/ti/ti_factory_data_user_guide.md rename to docs/guides/ti/matter-users-guide/ti_factory_data_user_guide.md index 50dfc41b15231d..4081b0239cda31 100644 --- a/docs/guides/ti/ti_factory_data_user_guide.md +++ b/docs/guides/ti/matter-users-guide/ti_factory_data_user_guide.md @@ -16,8 +16,7 @@ programming infrastructure for their Matter devices. TI Matter examples allow the use of factory data in the following two ways: - **Example Out of Box Factory Data** : Use TI example DAC values to get - started. This is intended to be used when just starting with Matter or - during development until customer or product specific data is not required. + started. This is intended to be used during development. - **Custom factory data** : Allows users to configure custom factory data via a JSON file. The custom values are then processed by a script provided by TI and merged with the Matter application to create a binary that can be @@ -50,9 +49,9 @@ Each element is described in more detail below: ## How to use -Out of box factory data location is configured to be on second last page of -flash. For CC13x4, the starting address is `0xFE800`. This can be configured in -the linker file. +Out of box factory data location is configured to be on second to last page of +flash. For CC13x4_CC26x4, the starting address is `0xFE800`. This can be +configured in the linker file. To configure: @@ -94,7 +93,7 @@ FLASH_FACTORY_DATA (R) : ORIGIN = 0x000fe800, LENGTH = 0x00000900 3. In the example's args.gni file, set 'custom_factory_data' to true -It is recommended to keep 2 dedicated pages for CC13x4 for factory data. +It is recommended to keep 2 dedicated pages for CC13x4_CC26x4 for factory data. ### Formatting certs and keys for JSON file diff --git a/docs/guides/ti/ti_openthread_library_usage.md b/docs/guides/ti/matter-users-guide/ti_openthread_library_usage.md similarity index 57% rename from docs/guides/ti/ti_openthread_library_usage.md rename to docs/guides/ti/matter-users-guide/ti_openthread_library_usage.md index 2b209fca44e744..d6412c729d69fa 100644 --- a/docs/guides/ti/ti_openthread_library_usage.md +++ b/docs/guides/ti/matter-users-guide/ti_openthread_library_usage.md @@ -1,19 +1,27 @@ -# Configuring Openthread libraries on TI CC13x4 Platforms +# Configuring OpenThread libraries on TI CC13x4_CC26x4 Platforms ## Overview -TI Matter example applications provide configuration option for how Thread code -is included in the build. Thread code can be included in as (1) full source or -(2) as optimized for matter thread certified library. The library builds have -been optimized for matter to disable features such as Thread Joiner capability -in order to save on Flash/RAM usage. +TI Matter example applications provide configuration options for how Thread code +is included in the build. Thread code can be included in as: + +1. Thread certified library optimized for Matter (recommended for development + and production) +2. Full Source (can be used for development) +3. Custom option where customers can update the Thread config file to change the + included OpenThread feature set + +The library builds have been optimized for Matter to disable features such as +Thread Joiner capability in order to save on Flash/RAM usage. Refer to the +`ti_matter_production_certification.md` to get the cert ID for your Matter +certification application when using the certified Thread libraries from TI. Build arguments have been added to enable Matter applications to link against -certified Openthread FTD/MTD libraries or custom user libraries. +certified OpenThread FTD/MTD libraries or custom user libraries. ## Platform Code Changes -To configure a TI example to utilize either an Openthread source or library +To configure a TI example to utilize either an OpenThread source or library build, open up the `args.gni` file of the example: To configure the device as an FTD or MTD, set following parameter to either true @@ -23,7 +31,9 @@ or false respectively. chip_openthread_ftd = true ``` -- **Openthread Library From Source**: +- **TI Certified OpenThread Library**: + + - Typically this is used for development. 1. `ot_ti_lib_dir` Is set to an empty string @@ -31,18 +41,18 @@ chip_openthread_ftd = true ot_ti_lib_dir="" ``` - 2. `chip_openthread_target` Is set to an empty string + 2. `chip_openthread_target` Points to the TI certified library dependency ``` - chip_openthread_target = "" + chip_openthread_target = "${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert" ``` - 3. `openthread_external_platform` Points to the Openthread build dependency + 3. `openthread_external_platform` Points to the OpenThread build dependency ``` - openthread_external_platform="${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti" + `openthread_external_platform="${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti"` ``` -- **TI Certified Openthread Library**: +- **OpenThread Library From Source**: 1. `ot_ti_lib_dir` Is set to an empty string @@ -50,18 +60,21 @@ chip_openthread_ftd = true ot_ti_lib_dir="" ``` - 2. `chip_openthread_target` Points to the TI certified library dependency + 2. `chip_openthread_target` Is set to an empty string ``` - chip_openthread_target = "${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert" + chip_openthread_target = "" ``` - 3. `openthread_external_platform` Points to the Openthread build dependency + 3. `openthread_external_platform` Points to the OpenThread build dependency ``` - `openthread_external_platform="${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti"` + openthread_external_platform="${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti" ``` -- **Custom Openthread Library**: +- **Custom OpenThread Library**: + + - The custom OpenThread library is used to implement extra features, or + when modifying the stack in anyway. 1. `ot_ti_lib_dir` Points to a library directory containing a custom `libopenthread-ftd/mtd` variant @@ -76,24 +89,24 @@ chip_openthread_ftd = true chip_openthread_target = "" ``` - 3. `openthread_external_platform` Points to the Openthread build dependency + 3. `openthread_external_platform` Points to the OpenThread build dependency ``` openthread_external_platform="${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti" ``` -The TI Openthread certified library for the MTD/FTD configurations is based on +The TI OpenThread certified library for the MTD/FTD configurations is based on the following header file: - `third_party/openthread/ot-ti/src/openthread-core-cc13xx_cc26xx-config-matter.h` -In order to update the Openthread configuration when building from source or a +In order to update the OpenThread configuration when building from source or a custom library, users may adjust features via the following configuration header file: - `${chip_root}/examples/platform/cc13x4_26x4/project_include/OpenThreadConfig.h` -Please refer to TI's standalone Openthread Application build process for +Please refer to TI's standalone OpenThread Application build process for instructions on acquiring FTD/MTD libraries as they are automatically built when generating the standalone applications. diff --git a/docs/guides/ti/ti_matter_overview.md b/docs/guides/ti/ti_matter_overview.md new file mode 100644 index 00000000000000..44943fa46ba871 --- /dev/null +++ b/docs/guides/ti/ti_matter_overview.md @@ -0,0 +1,173 @@ +```{toctree} +:glob: +:maxdepth: 1 +:hidden: + +matter-migration-guide/matter_cc2674_migration.md +matter-syscfg/getting-started.md +matter-syscfg/sysconfig-board.md +matter-users-guide/ti_openthread_library_usage.md +matter-users-guide/ti_factory_data_user_guide.md +matter-users-guide/enabling_icd_on_ti_devices.md +``` + +# Texas Instruments platform overview + +The Texas Instruments Matter platform is based on the TI SimpleLinkâ„¢ SDK. + +The following diagram is a simplified representation of a Matter application +which is built on the TI Platform. + +
    + +
    + +## Texas Instruments SimpleLink SDK + +This Matter GitHub repository contains the software development components and +tools that enable engineers to develop Matter based products. This repository is +the starting point for Matter development on all SimpleLink Thread and Wi-Fi +wireless microcontrollers (MCUs). + +The SimpleLink MCU portfolio offers a single development environment that +delivers flexible hardware, software, and tool options for customers developing +wired and wireless applications. With 100 percent code reuse across host MCUs, +Wi-Fiâ„¢, Bluetooth Low Energy, 2.4GHz, Sub-1GHz devices and more, choose the MCU +or connectivity standard that fits your design. A one-time investment with the +SimpleLink software development kit allows you to reuse often, opening the door +to create unlimited applications. For more information, visit +www.ti.com/simplelink. + +
    + +## Bluetooth LE and Thread stacks + +In the TI example applications the Bluetooth Low Energy protocol is used to +provision the Thread protocol to enable Matter communication. Then Thread is +used for IP communication with other Matter devices. + +The TI applications leverage the Bluetooth Low Energy stack on the CC13XX and +CC26XX families. This Bluetooth LE software is distributed in binary form within +the TI SimpleLink SDK. The Bluetooth LE stack leverages code that is present in +the device ROM for certain common Bluetooth LE operations. + +These applications leverage the OpenThread stack available within the Matter +repository for Thread communication. Platform support source is built from the +SimpleLink SDK. + +These connection protocols can be run concurrently by using the Texas +Instruments Dynamic Multi-protocol Manager. + +
    + +## LwIP stack + +The Lightweight IP stack interfaces with the OpenThread stack to offer standard +IP connectivity protocols that OpenThread does not natively support. This offers +a standard socket based interface to the Matter platform. + +
    + +## MbedTLS + +The MbedTLS library is used by OpenThread and Matter for a wide variety of +protocols. This ranges from basic AES and SHA to cryptographic protocols like +ECDSA and ECDH. + +The MbedTLS library is hardware accelerated using the TI SimpleLink SDK drivers. +This is achieved through the usage of `_ALT` defines in the MbedTLS +configuration file. + +
    + +## Matter Stack to TI Platform Interface + +Matter Stack interacts with LwIP, OpenThread, and the TI-BLE stack to achieve +the protocol and application functionality. A Bluetooth LE profile is registered +with the TI-BLE stack to enable provisioning and configuration. Once the device +is provisioned Matter will configure the OpenThread interface to connect to an +existing Thread network or to start its own network. From there the Matter IP +messages are sent to the LwIP stack to be routed to the OpenThread stack for +transmission. Matter Impl (Implementation) layer acts as an interface between +Matter stack and the TI platform components such as BLE stack, OpenThread, +FreeRTOS. It also supports components such as connectivity manager that provides +the implementation for functionality required by Matter stack. Overall, +applications generally only need to interface with the Cluster Library from +Matter. The transport of messages and configuration of the device is all handled +by the platform implementation files. + +
    + +## Matter Development Resources + +Below are several resources available for Matter development: + +- [Matter Protocol Overview](https://handbook.buildwithmatter.com/howitworks/roles/) +- [Matter Build Guide](../BUILDING.md) +- [Matter over Thread Getting Started](https://dev.ti.com/tirex/explore/node?node=A__AciOYyNq9gli.nsvJzBtQg__com.ti.SIMPLELINK_ACADEMY_CC13XX_CC26XX_SDK__AfkT0vQ__LATEST) +- [TI Matter over Wi-Fi Getting Started](https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1122413/faq-cc3235sf-matter----getting-started-guide) +- [TI Matter Application Development](https://dev.ti.com/tirex/explore/node?node=A__AXNOPYikmtBCHJ-L6eRivA__com.ti.SIMPLELINK_ACADEMY_CC13XX_CC26XX_SDK__AfkT0vQ__LATEST) +- [TI Matter OTA Guide](https://dev.ti.com/tirex/explore/node?node=A__AYTiKtu5heqgH4KPFa.6RQ__com.ti.SIMPLELINK_ACADEMY_CC13XX_CC26XX_SDK__AfkT0vQ__LATEST) + +
    + +## Matter Example Applications + +Sample Matter applications are provided for the TI platform. These can be used +as reference for your own application. + +- [lock-app](../../../examples/lock-app/cc13x4_26x4/README.md) +- [pump-app](../../../examples/pump-app/cc13x4_26x4/README.md) +- [pump-controller-app](../../../examples/pump-controller-app/cc13x4_26x4/README.md) +- [lighting-app](../../../examples/lighting-app/cc13x4_26x4/README.md) +
    + +### Build system + +The TI platform uses GN to generate ninja build scripts. Build files have +already been written to build and link the TI specific code within the +SimpleLink SDK. + +
    + +## CC2674 Migration + +For instructions on how to migrate the CC1354P10-6 examples to either the +CC2674P10 or the CC2674R10, please refer to the guide linked below. + +- [TI CC2674 Migration Guide](./matter-migration-guide/matter_cc2674_migration.md) + +
    + +## Factory Data Programming Tool + +For instructions on how to program custom factory data on TI devices, please +refer to the guide linked below. + +- [TI Factory Data User Guide](./matter-users-guide/ti_factory_data_user_guide.md) + +
    + +## Intermittently Connected Devices + +For instructions on how to use the Matter ICD feature on TI devices, please +refer to the guide linked below. + +- [Enabling ICD On TI Devices](./matter-users-guide/enabling_icd_on_ti_devices.md) + +
    + +## Matter OpenThread Library Configuration + +For instructions on how to configure the OpenThread build configuration for a +Matter application, please refer to the guide linked below. + +- [OpenThread Library Configuration](./matter-users-guide/ti_openthread_library_usage.md) + +### TI Support + +For technical support, please consider creating a post on TI's [E2E forum][e2e]. +Additionally, we welcome any feedback. + +[e2e]: https://e2e.ti.com/support/wireless-connectivity/zigbee-and-thread +[matter_gh]: https://github.com/project-chip/connectedhomeip diff --git a/docs/guides/ti/ti_platform_overview.md b/docs/guides/ti/ti_platform_overview.md deleted file mode 100644 index bae464ac107224..00000000000000 --- a/docs/guides/ti/ti_platform_overview.md +++ /dev/null @@ -1,162 +0,0 @@ -```{toctree} -:glob: -:maxdepth: 1 - -* -``` - -# Texas Instruments platform overview - -The TI platform is a [Matter][matter_gh] platform based on the Texas Instruments -Incorporated SimpleLink SDK. - -The following diagram is a simplified representation of a Matter application -which built on the TI Platform. - -![matter_ti_overview_simplified](./../images/matter_ti_overview_simplified.png) - -## Texas Instruments SimpleLink SDK - -The SimpleLink™ CC13xx and CC26xx Software Development Kit (SDK) delivers -components that enable engineers to develop applications on the Texas -Instruments SimpleLink CC13xx and CC26xx family of wireless microcontrollers -(MCUs). This software toolkit provides a cohesive and consistent software -experience for all SimpleLink CC13xx and CC26xx wireless MCU users by packaging -essential software components, such as a Bluetooth® Low Energy (BLE) protocol -stack supporting Bluetooth 5.2, Bluetooth Mesh, Thread 1.1.1 networking stack -based on OpenThread, Zigbee 3.0 compliant protocol suite, RF-Proprietary -examples, TI’s 15.4 Stack as well as the TI-RTOS kernel and TI Drivers in one -easy-to-use software package along with example applications and documentation. -In addition, the Dynamic Multi-Protocol Manager (DMM) software component enables -multiprotocol development on a single SimpleLink wireless MCU through -time-division multiplexing. - -The SimpleLink MCU portfolio offers a single development environment that -delivers flexible hardware, software, and tool options for customers developing -wired and wireless applications. With 100 percent code reuse across host MCUs, -Wi-Fi™, Bluetooth Low Energy, Sub-1GHz devices and more, choose the MCU or -connectivity standard that fits your design. A one-time investment with the -SimpleLink software development kit allows you to reuse often, opening the door -to create unlimited applications. For more information, visit -www.ti.com/simplelink. - -
    - -## BLE and Thread stacks - -In the TI example applications the Bluetooth Low Energy protocol is used to -provision the Thread protocol to enable Matter communication. Then Thread is -used for IP communication with other Matter devices. - -The TI applications leverage the Bluetooth Low Energy stack on the CC13XX and -CC26XX families. This BLE software is distributed in binary form within the TI -SimpleLink SDK. The BLE stack leverages code that is present in the device ROM -for certain common BLE operations. - -These applications leverage the OpenThread stack available within the Matter -repository for Thread communication. Platform support source is built from the -SimpleLink SDK. - -These connection protocols can be run concurrently by using the Texas -Instruments Dynamic Multi-protocol Manager. - -
    - -## LwIP stack - -The Lightweight IP stack interfaces with the OpenThread stack to offer standard -IP connectivity protocols that OpenThread does not natively support. This offers -a standard socket based interface to the Matter platform. - -
    - -## MbedTLS - -The MbedTLS library is used by OpenThread and Matter for a wide variety of -protocols. This ranges from basic AES and SHA to cryptographic protocols like -ECDSA and ECDH. - -The MbedTLS library is hardware accelerated using the TI SimpleLink SDK drivers. -This is achieved through the usage of `_ALT` defines in the MbedTLS -configuration file. - -
    - -## Matter integration - -Matter interacts with LwIP, OpenThread, and the TI BLE stack to achieve the -protocol and application functionality. A BLE profile is registered with the -TI-BLE stack to enable provisioning and configuration. Once the device is -provisioned Matter will configure the OpenThread interface to connect to an -existing Thread network or to start its own network. From there the Matter IP -messages are sent to the LwIP stack to be routed to the OpenThread stack for -transmission. - -Overall, applications generally only need to interface with the Cluster Library -from Matter. The transport of messages and configuration of the device is all -handled by the platform implementation files. - -
    - -## Matter example applications - -Sample Matter applications are provided for the TI platform. These can be used -as reference for your own application. - -- [lock-app](../../../examples/lock-app/cc13x4_26x4/README.md) -- [pump-app](../../../examples/pump-app/cc13x4_26x4/README.md) -- [pump-controller-app](../../../examples/pump-controller-app/cc13x4_26x4/README.md) - -
    - -### Build system - -The TI platform uses GN to generate ninja build scripts. Build files have -already been written to build and link the TI specific code within the -SimpleLink SDK. - -
    - -## CC2674 Migration - -For instructions on how to migrate the CC1354P10-6 examples to either the -CC2674P10 or the CC2674R10, please refer to the guide linked below. - -- [TI CC2674 Migration Guide](./matter_cc2674_migration.md) - -
    - -## Factory Data Programming Tool - -For instructions on how to program custom factory data on TI devices, please -refer to the guide linked below. - -- [TI Factory Data User Guide](./ti_factory_data_user_guide.md) - -
    - -## Intermittently Connected Devices - -For instructions on how to use Matters' ICD feature on TI devices, please refer -to the guide linked below. - -- [Enabling ICD On TI Devices](./enabling_icd_on_ti_devices.md) - -
    - -## Matter Openthread Library Configuration - -For instructions on how to configure the Openthread build configuration for a -Matter application, please refer to the guide linked below. - -- [Openthread Library Configuration](./ti_openthread_library_usage.md) - -
    - -### TI Support - -For technical support, please consider creating a post on TI's [E2E forum][e2e]. -Additionally, we welcome any feedback. - -[e2e]: https://e2e.ti.com/support/wireless-connectivity/zigbee-and-thread -[matter_gh]: https://github.com/project-chip/connectedhomeip diff --git a/docs/images/ti_logo.png b/docs/images/ti_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e860023a5d60bafd77206650006bbe1b8f36e53a GIT binary patch literal 4375 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 N_BKveaaR6m{{>=xUrqo3 literal 0 HcmV?d00001 diff --git a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn index be89a8b3aecd80..2a5609fb98b928 100644 --- a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn +++ b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn @@ -78,6 +78,7 @@ ti_simplelink_executable("all-clusters-app") { "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerHandler.cpp", "${project_dir}/main/AppTask.cpp", "${project_dir}/main/ClusterManager.cpp", "${project_dir}/main/Globals.cpp", @@ -85,6 +86,10 @@ ti_simplelink_executable("all-clusters-app") { "${project_dir}/main/main.cpp", ] + public = [ + "${chip_root}/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.h", + ] + deps = [ ":sdk", ":sysconfig", diff --git a/examples/all-clusters-app/cc13x4_26x4/README.md b/examples/all-clusters-app/cc13x4_26x4/README.md index 4cb76380ce2df4..be6a38277edafc 100644 --- a/examples/all-clusters-app/cc13x4_26x4/README.md +++ b/examples/all-clusters-app/cc13x4_26x4/README.md @@ -65,10 +65,16 @@ guide assumes that the environment is linux based, and recommends Ubuntu 20.04. ``` - Run the bootstrap script to setup the build environment. +- Note, a recursive submodule checkout is required to utilize TI's Openthread + reference commit. +- Note, in order to build the chip-tool and ota-provider examples, a recursive + submodule checkout is required for the linux platform as seen in the command + below. ``` $ cd ~/connectedhomeip $ source ./scripts/bootstrap.sh + $ ./scripts/checkout_submodules.py --shallow --platform cc13xx_26xx linux --recursive ``` diff --git a/examples/all-clusters-app/cc13x4_26x4/args.gni b/examples/all-clusters-app/cc13x4_26x4/args.gni index bebfb47fa12665..56b7504ebf03f5 100644 --- a/examples/all-clusters-app/cc13x4_26x4/args.gni +++ b/examples/all-clusters-app/cc13x4_26x4/args.gni @@ -32,7 +32,11 @@ chip_enable_ota_requestor = true openthread_external_platform = "${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti" -chip_openthread_target = "" + +# When using TI Certified Openthread libs set to ${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert +# For source builds, set to empty string. +chip_openthread_target = + "${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert" chip_openthread_ftd = true @@ -61,3 +65,8 @@ chip_persist_subscriptions = false chip_subscription_timeout_resumption = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" + +if (chip_openthread_target != "") { + openthread_root = + "//third_party/connectedhomeip/third_party/openthread/ot-ti/openthread" +} diff --git a/examples/all-clusters-app/cc13x4_26x4/chip.syscfg b/examples/all-clusters-app/cc13x4_26x4/chip.syscfg index e4ae2b6acfbbd2..16ce3520e42674 100644 --- a/examples/all-clusters-app/cc13x4_26x4/chip.syscfg +++ b/examples/all-clusters-app/cc13x4_26x4/chip.syscfg @@ -89,8 +89,8 @@ CCFG.enableCodeGeneration = false; /* NVS */ NVS1.$name = "CONFIG_NVSINTERNAL"; -NVS1.internalFlash.regionBase = 0xFB800; -NVS1.internalFlash.regionSize = 0x2800; +NVS1.internalFlash.regionBase = 0xF8800; +NVS1.internalFlash.regionSize = 0x6000; NVS2.$name = "CONFIG_NVSEXTERNAL"; diff --git a/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp b/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp index 6fc9642b8c063a..98926214c4cb36 100644 --- a/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp @@ -45,6 +45,10 @@ #endif #include +#include +#include +#include + #include #include @@ -56,6 +60,8 @@ #define APP_EVENT_QUEUE_SIZE 10 #define BUTTON_ENABLE 1 +#define OTAREQUESTOR_INIT_TIMER_DELAY_MS 10000 + using namespace ::chip; using namespace ::chip::Credentials; using namespace ::chip::DeviceLayer; @@ -70,6 +76,12 @@ AppTask AppTask::sAppTask; constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; +void StartTimer(uint32_t aTimeoutMs); +void CancelTimer(void); + +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR static DefaultOTARequestor sRequestorCore; static DefaultOTARequestorStorage sRequestorStorage; @@ -90,6 +102,15 @@ void InitializeOTARequestor(void) } #endif +TimerHandle_t sOTAInitTimer = 0; + +// The OTA Init Timer is only started upon the first Thread State Change +// detected if the device is already on a Thread Network, or during the AppTask +// Init sequence if the device is not yet on a Thread Network. Once the timer +// has been started once, it does not need to be started again so the flag will +// be set to false. +bool isAppStarting = true; + #ifdef AUTO_PRINT_METRICS static void printMetrics(void) { @@ -132,6 +153,22 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) case DeviceEventType::kCommissioningComplete: PLAT_LOG("Commissioning complete"); break; + case DeviceEventType::kThreadStateChange: + PLAT_LOG("Thread State Change"); + bool isThreadAttached = ThreadStackMgrImpl().IsThreadAttached(); + + if (isThreadAttached) + { + PLAT_LOG("Device is on the Thread Network"); +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + if (isAppStarting) + { + StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); + isAppStarting = false; + } +#endif + } + break; } #ifdef AUTO_PRINT_METRICS @@ -139,6 +176,11 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) #endif } +void OTAInitTimerEventHandler(TimerHandle_t xTimer) +{ + InitializeOTARequestor(); +} + int AppTask::StartAppTask() { int ret = 0; @@ -171,6 +213,9 @@ int AppTask::Init() // Init Chip memory management before the stack Platform::MemoryInit(); + PLAT_LOG("Software Version: %d", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION); + PLAT_LOG("Software Version String: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); + CHIP_ERROR ret = PlatformMgr().InitChipStack(); if (ret != CHIP_NO_ERROR) { @@ -179,6 +224,23 @@ int AppTask::Init() ; } + // Create FreeRTOS sw timer for OTA timer. + sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel + OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = light obj context + OTAInitTimerEventHandler // timer callback handler + ); + + if (sOTAInitTimer == NULL) + { + PLAT_LOG("sOTAInitTimer timer create failed"); + } + else + { + PLAT_LOG("sOTAInitTimer timer created successfully "); + } + ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) { @@ -202,14 +264,6 @@ int AppTask::Init() ; } - ret = PlatformMgr().StartEventLoopTask(); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); - while (1) - ; - } - ret = ThreadStackMgrImpl().StartThreadTask(); if (ret != CHIP_NO_ERROR) { @@ -234,6 +288,9 @@ int AppTask::Init() // Init ZCL Data Model and start server PLAT_LOG("Initialize Server"); static chip::CommonCaseDeviceServerInitParams initParams; + static DefaultTestEventTriggerDelegate sTestEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); // Initialize info provider @@ -242,6 +299,14 @@ int AppTask::Init() chip::Server::GetInstance().Init(initParams); + ret = PlatformMgr().StartEventLoopTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); + while (1) + ; + } + ConfigurationMgr().LogDeviceConfig(); // We only have network commissioning on endpoint 0. @@ -251,9 +316,15 @@ int AppTask::Init() // this function will happen on the CHIP event loop thread, not the app_main thread. PlatformMgr().AddEventHandler(DeviceEventCallback, reinterpret_cast(nullptr)); + bool isThreadEnabled = ThreadStackMgrImpl().IsThreadEnabled(); + if (!isThreadEnabled && isAppStarting) + { #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - InitializeOTARequestor(); + PLAT_LOG("Thread is Disabled, enable OTA Requestor"); + StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); + isAppStarting = false; #endif + } // QR code will be used with CHIP Tool PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE)); @@ -276,6 +347,32 @@ void AppTask::AppTaskMain(void * pvParameter) } } +void StartTimer(uint32_t aTimeoutMs) +{ + PLAT_LOG("Start OTA Init Timer") + if (xTimerIsTimerActive(sOTAInitTimer)) + { + PLAT_LOG("app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sOTAInitTimer, pdMS_TO_TICKS(aTimeoutMs), 100) != pdPASS) + { + PLAT_LOG("sOTAInitTimer timer start() failed"); + } +} + +void CancelTimer(void) +{ + if (xTimerStop(sOTAInitTimer, 0) == pdFAIL) + { + PLAT_LOG("sOTAInitTimer stop() failed"); + } +} + void AppTask::PostEvent(const AppEvent * aEvent) { if (xQueueSend(sAppEventQueue, aEvent, 0) != pdPASS) diff --git a/examples/lighting-app/cc13x4_26x4/BUILD.gn b/examples/lighting-app/cc13x4_26x4/BUILD.gn index d3c0df34e6ce3d..38bb95ce8d53d7 100644 --- a/examples/lighting-app/cc13x4_26x4/BUILD.gn +++ b/examples/lighting-app/cc13x4_26x4/BUILD.gn @@ -65,12 +65,17 @@ ti_simplelink_executable("lighting_app") { sources = [ "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerHandler.cpp", "${project_dir}/src/AppTask.cpp", "${project_dir}/src/LightingManager.cpp", "${project_dir}/src/ZclCallbacks.cpp", "${project_dir}/src/main.cpp", ] + public = [ + "${chip_root}/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.h", + ] + deps = [ ":sdk", ":sysconfig", diff --git a/examples/lighting-app/cc13x4_26x4/README.md b/examples/lighting-app/cc13x4_26x4/README.md index 40dc195b218399..73718a0bf76a86 100644 --- a/examples/lighting-app/cc13x4_26x4/README.md +++ b/examples/lighting-app/cc13x4_26x4/README.md @@ -64,10 +64,16 @@ guide assumes that the environment is linux based, and recommends Ubuntu 20.04. ``` - Run the bootstrap script to setup the build environment. +- Note, a recursive submodule checkout is required to utilize TI's Openthread + reference commit. +- Note, in order to build the chip-tool and ota-provider examples, a recursive + submodule checkout is required for the linux platform as seen in the command + below. ``` $ cd ~/connectedhomeip $ source ./scripts/bootstrap.sh + $ ./scripts/checkout_submodules.py --shallow --platform cc13xx_26xx linux --recursive ``` @@ -101,7 +107,6 @@ Ninja to build the executable. If you would like to define arguments on the command line you may add them to the GN call. - ``` gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" ``` diff --git a/examples/lighting-app/cc13x4_26x4/args.gni b/examples/lighting-app/cc13x4_26x4/args.gni index 823c0385aeb643..2c9257e09e9a68 100644 --- a/examples/lighting-app/cc13x4_26x4/args.gni +++ b/examples/lighting-app/cc13x4_26x4/args.gni @@ -30,13 +30,16 @@ lwip_debug = false chip_enable_ota_requestor = true -chip_openthread_ftd = true +chip_openthread_ftd = false ot_ti_lib_dir = "" openthread_external_platform = "${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti" -chip_openthread_target = "" +# When using TI Certified Openthread libs set to ${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert +# For source builds, set to empty string. +chip_openthread_target = + "${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert" # Disable CHIP Logging chip_progress_logging = true @@ -55,7 +58,7 @@ matter_device_pid = "0x8005" matter_software_ver = "0x0001" matter_software_ver_str = "1.0.1+1" -custom_factory_data = true +custom_factory_data = false # ICD Default configurations # when enabled the device will be configured as a sleepy end device @@ -64,3 +67,8 @@ chip_persist_subscriptions = false chip_subscription_timeout_resumption = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" + +if (chip_openthread_target != "") { + openthread_root = + "//third_party/connectedhomeip/third_party/openthread/ot-ti/openthread" +} diff --git a/examples/lighting-app/cc13x4_26x4/chip.syscfg b/examples/lighting-app/cc13x4_26x4/chip.syscfg index e4ae2b6acfbbd2..57ba89574d53cf 100644 --- a/examples/lighting-app/cc13x4_26x4/chip.syscfg +++ b/examples/lighting-app/cc13x4_26x4/chip.syscfg @@ -16,7 +16,6 @@ * limitations under the License. */ - /* Modules */ var AESCCM = scripting.addModule("/ti/drivers/AESCCM"); var AESECB = scripting.addModule("/ti/drivers/AESECB"); @@ -89,8 +88,8 @@ CCFG.enableCodeGeneration = false; /* NVS */ NVS1.$name = "CONFIG_NVSINTERNAL"; -NVS1.internalFlash.regionBase = 0xFB800; -NVS1.internalFlash.regionSize = 0x2800; +NVS1.internalFlash.regionBase = 0xF8800; +NVS1.internalFlash.regionSize = 0x6000; NVS2.$name = "CONFIG_NVSEXTERNAL"; diff --git a/examples/lighting-app/cc13x4_26x4/src/AppEvent.h b/examples/lighting-app/cc13x4_26x4/src/AppEvent.h index b6138ec479949c..3edcc4e4809faf 100644 --- a/examples/lighting-app/cc13x4_26x4/src/AppEvent.h +++ b/examples/lighting-app/cc13x4_26x4/src/AppEvent.h @@ -34,6 +34,7 @@ struct AppEvent kEventType_IdentifyStop, kEventType_Light, kEventType_Timer, + kEventType_Identify, }; enum AppEventButtonType diff --git a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp index 5b5bb7d7df222f..aa9bdbccefa3c3 100644 --- a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp @@ -48,6 +48,10 @@ #include #include +#include +#include +#include + #include #include @@ -74,6 +78,8 @@ static uint32_t identify_trigger_effect = IDENTIFY_TRIGGER_EFFECT_FINISH_STOP; #endif #define BUTTON_ENABLE 1 +#define OTAREQUESTOR_INIT_TIMER_DELAY_MS 10000 + using namespace ::chip; using namespace ::chip::app; using namespace ::chip::Credentials; @@ -96,6 +102,12 @@ void uiTurnedOn(void); void uiTurnOff(void); void uiTurnedOff(void); +void StartTimer(uint32_t aTimeoutMs); +void CancelTimer(void); + +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR static DefaultOTARequestor sRequestorCore; static DefaultOTARequestorStorage sRequestorStorage; @@ -116,6 +128,15 @@ void InitializeOTARequestor(void) } #endif +TimerHandle_t sOTAInitTimer = 0; + +// The OTA Init Timer is only started upon the first Thread State Change +// detected if the device is already on a Thread Network, or during the AppTask +// Init sequence if the device is not yet on a Thread Network. Once the timer +// has been started once, it does not need to be started again so the flag will +// be set to false. +bool isAppStarting = true; + ::Identify stIdentify = { LIGHTING_APPLICATION_IDENTIFY_ENDPOINT, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, AppTask::TriggerIdentifyEffectHandler }; @@ -160,6 +181,45 @@ void identify_StopAction(void) #endif // LED_ENABLE } +void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEConnectionEstablished: + PLAT_LOG("CHIPoBLE connection established"); + break; + + case DeviceEventType::kCHIPoBLEConnectionClosed: + PLAT_LOG("CHIPoBLE disconnected"); + break; + + case DeviceEventType::kCommissioningComplete: + PLAT_LOG("Commissioning complete"); + break; + case DeviceEventType::kThreadStateChange: + PLAT_LOG("Thread State Change"); + bool isThreadAttached = ThreadStackMgrImpl().IsThreadAttached(); + + if (isThreadAttached) + { + PLAT_LOG("Device is on the Thread Network"); +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + if (isAppStarting) + { + StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); + isAppStarting = false; + } +#endif + } + break; + } +} + +void OTAInitTimerEventHandler(TimerHandle_t xTimer) +{ + InitializeOTARequestor(); +} + int AppTask::Init() { cc13xx_26xxLogInit(); @@ -167,14 +227,35 @@ int AppTask::Init() // Init Chip memory management before the stack Platform::MemoryInit(); + PLAT_LOG("Software Version: %d", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION); + PLAT_LOG("Software Version String: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); + CHIP_ERROR ret = PlatformMgr().InitChipStack(); if (ret != CHIP_NO_ERROR) { + PLAT_LOG("PlatformMgr().InitChipStack() failed"); while (1) ; } + // Create FreeRTOS sw timer for OTA timer. + sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel + OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = light obj context + OTAInitTimerEventHandler // timer callback handler + ); + + if (sOTAInitTimer == NULL) + { + PLAT_LOG("sOTAInitTimer timer create failed"); + } + else + { + PLAT_LOG("sOTAInitTimer timer created successfully "); + } + ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) { @@ -182,6 +263,7 @@ int AppTask::Init() while (1) ; } + #if CHIP_DEVICE_CONFIG_THREAD_FTD ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); #elif CHIP_CONFIG_ENABLE_ICD_SERVER @@ -197,14 +279,6 @@ int AppTask::Init() ; } - ret = PlatformMgr().StartEventLoopTask(); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); - while (1) - ; - } - ret = ThreadStackMgrImpl().StartThreadTask(); if (ret != CHIP_NO_ERROR) { @@ -229,6 +303,9 @@ int AppTask::Init() // Init ZCL Data Model and start server PLAT_LOG("Initialize Server"); static CommonCaseDeviceServerInitParams initParams; + static DefaultTestEventTriggerDelegate sTestEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); // Initialize info provider @@ -237,6 +314,16 @@ int AppTask::Init() Server::GetInstance().Init(initParams); + ret = PlatformMgr().StartEventLoopTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); + while (1) + ; + } + + PlatformMgr().AddEventHandler(DeviceEventCallback, reinterpret_cast(nullptr)); + uiInit(); ret = LightMgr().Init(); @@ -252,9 +339,15 @@ int AppTask::Init() ConfigurationMgr().LogDeviceConfig(); + bool isThreadEnabled = ThreadStackMgrImpl().IsThreadEnabled(); + if (!isThreadEnabled && isAppStarting) + { #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - InitializeOTARequestor(); + PLAT_LOG("Thread is Disabled, enable OTA Requestor"); + StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); + isAppStarting = false; #endif + } // QR code will be used with CHIP Tool PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE)); @@ -278,6 +371,32 @@ void AppTask::AppTaskMain(void * pvParameter) } } +void StartTimer(uint32_t aTimeoutMs) +{ + PLAT_LOG("Start OTA Init Timer") + if (xTimerIsTimerActive(sOTAInitTimer)) + { + PLAT_LOG("app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sOTAInitTimer, pdMS_TO_TICKS(aTimeoutMs), 100) != pdPASS) + { + PLAT_LOG("sOTAInitTimer timer start() failed"); + } +} + +void CancelTimer(void) +{ + if (xTimerStop(sOTAInitTimer, 0) == pdFAIL) + { + PLAT_LOG("sOTAInitTimer stop() failed"); + } +} + void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) { if (aAction == LightingManager::ON_ACTION) @@ -406,6 +525,14 @@ void AppTask::DispatchEvent(AppEvent * aEvent) PLAT_LOG("Identify started"); break; + case AppEvent::kEventType_Identify: + // blink LED + PLAT_LOG("Identify cmd received, will blink green led three times now"); +#if (LED_ENABLE == 1) + LED_startBlinking(sAppGreenHandle, 250, 3); +#endif + break; + case AppEvent::kEventType_IdentifyStop: identify_StopAction(); PLAT_LOG("Identify stopped"); diff --git a/examples/lighting-app/cc13x4_26x4/src/LightingManager.cpp b/examples/lighting-app/cc13x4_26x4/src/LightingManager.cpp index ed5fc52e7e5638..cd84fe48b39056 100644 --- a/examples/lighting-app/cc13x4_26x4/src/LightingManager.cpp +++ b/examples/lighting-app/cc13x4_26x4/src/LightingManager.cpp @@ -174,3 +174,10 @@ void LightingManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) } } } + +void LightingManager::IdentifyEventHandler() +{ + AppEvent event; + event.Type = AppEvent::kEventType_Identify; + AppTask::GetAppTask().PostEvent(&event); +} diff --git a/examples/lighting-app/cc13x4_26x4/src/LightingManager.h b/examples/lighting-app/cc13x4_26x4/src/LightingManager.h index 818feed45ee87a..a87e3a3d806dc0 100644 --- a/examples/lighting-app/cc13x4_26x4/src/LightingManager.h +++ b/examples/lighting-app/cc13x4_26x4/src/LightingManager.h @@ -36,6 +36,7 @@ class LightingManager { ON_ACTION = 0, OFF_ACTION, + IDENTIFY_ACTION, INVALID_ACTION } Action; @@ -58,6 +59,7 @@ class LightingManager void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); static void OnTriggerOffWithEffect(OnOffEffect * effect); + void IdentifyEventHandler(); private: friend LightingManager & LightMgr(void); diff --git a/examples/lighting-app/cc13x4_26x4/src/ZclCallbacks.cpp b/examples/lighting-app/cc13x4_26x4/src/ZclCallbacks.cpp index 7bb20a45944545..8191935e0878f1 100644 --- a/examples/lighting-app/cc13x4_26x4/src/ZclCallbacks.cpp +++ b/examples/lighting-app/cc13x4_26x4/src/ZclCallbacks.cpp @@ -46,6 +46,7 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & { ChipLogProgress(Zcl, "Identify attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", ChipLogValueMEI(attributeId), type, *value, size); + LightMgr().IdentifyEventHandler(); } else if (clusterId == Groups::Id) { diff --git a/examples/lock-app/cc13x4_26x4/BUILD.gn b/examples/lock-app/cc13x4_26x4/BUILD.gn index 638e26cafb683d..92c1fc8bf9acb1 100644 --- a/examples/lock-app/cc13x4_26x4/BUILD.gn +++ b/examples/lock-app/cc13x4_26x4/BUILD.gn @@ -73,12 +73,17 @@ ti_simplelink_executable("lock_app") { sources = [ "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerHandler.cpp", "${project_dir}/src/AppTask.cpp", "${project_dir}/src/LockManager.cpp", "${project_dir}/src/ZclCallbacks.cpp", "${project_dir}/src/main.cpp", ] + public = [ + "${chip_root}/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.h", + ] + deps = [ ":sdk", ":sysconfig", diff --git a/examples/lock-app/cc13x4_26x4/README.md b/examples/lock-app/cc13x4_26x4/README.md index b8b43d6ec6a218..7ff622a8e14f90 100644 --- a/examples/lock-app/cc13x4_26x4/README.md +++ b/examples/lock-app/cc13x4_26x4/README.md @@ -65,10 +65,16 @@ guide assumes that the environment is linux based, and recommends Ubuntu 20.04. ``` - Run the bootstrap script to setup the build environment. +- Note, a recursive submodule checkout is required to utilize TI's Openthread + reference commit. +- Note, in order to build the chip-tool and ota-provider examples, a recursive + submodule checkout is required for the linux platform as seen in the command + below. ``` $ cd ~/connectedhomeip $ source ./scripts/bootstrap.sh + $ ./scripts/checkout_submodules.py --shallow --platform cc13xx_26xx linux --recursive ``` @@ -102,7 +108,6 @@ Ninja to build the executable. If you would like to define arguments on the command line you may add them to the GN call. - ``` gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" ``` diff --git a/examples/lock-app/cc13x4_26x4/args.gni b/examples/lock-app/cc13x4_26x4/args.gni index ca53f6e3bbc603..c2e2e643a2f2ef 100644 --- a/examples/lock-app/cc13x4_26x4/args.gni +++ b/examples/lock-app/cc13x4_26x4/args.gni @@ -34,7 +34,11 @@ chip_openthread_ftd = true ot_ti_lib_dir = "" openthread_external_platform = "${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti" -chip_openthread_target = "" + +# When using TI Certified Openthread libs set to ${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert +# For source builds, set to empty string. +chip_openthread_target = + "${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert" # Disable CHIP Logging chip_progress_logging = true @@ -63,3 +67,8 @@ chip_persist_subscriptions = false chip_subscription_timeout_resumption = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" + +if (chip_openthread_target != "") { + openthread_root = + "//third_party/connectedhomeip/third_party/openthread/ot-ti/openthread" +} diff --git a/examples/lock-app/cc13x4_26x4/chip.syscfg b/examples/lock-app/cc13x4_26x4/chip.syscfg index e4ae2b6acfbbd2..8a0283b5db3ee5 100644 --- a/examples/lock-app/cc13x4_26x4/chip.syscfg +++ b/examples/lock-app/cc13x4_26x4/chip.syscfg @@ -89,9 +89,8 @@ CCFG.enableCodeGeneration = false; /* NVS */ NVS1.$name = "CONFIG_NVSINTERNAL"; -NVS1.internalFlash.regionBase = 0xFB800; -NVS1.internalFlash.regionSize = 0x2800; - +NVS1.internalFlash.regionBase = 0xF8800; +NVS1.internalFlash.regionSize = 0x6000; NVS2.$name = "CONFIG_NVSEXTERNAL"; NVS2.nvsType = "External"; // NVS Region Type diff --git a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp index 2a202ce432ed7a..b26bd6ae43f8c1 100644 --- a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp @@ -47,6 +47,10 @@ #include #include +#include +#include +#include + #include #include @@ -64,6 +68,8 @@ #endif #define BUTTON_ENABLE 1 +#define OTAREQUESTOR_INIT_TIMER_DELAY_MS 10000 + using namespace ::chip; using namespace ::chip::app; using namespace ::chip::Credentials; @@ -83,6 +89,17 @@ static DeviceInfoProviderImpl sExampleDeviceInfoProvider; AppTask AppTask::sAppTask; +void uiLocking(void); +void uiLocked(void); +void uiUnlocking(void); +void uiUnlocked(void); + +void StartTimer(uint32_t aTimeoutMs); +void CancelTimer(void); + +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR static DefaultOTARequestor sRequestorCore; static DefaultOTARequestorStorage sRequestorStorage; @@ -103,6 +120,15 @@ void InitializeOTARequestor(void) } #endif +TimerHandle_t sOTAInitTimer = 0; + +// The OTA Init Timer is only started upon the first Thread State Change +// detected if the device is already on a Thread Network, or during the AppTask +// Init sequence if the device is not yet on a Thread Network. Once the timer +// has been started once, it does not need to be started again so the flag will +// be set to false. +bool isAppStarting = true; + ::Identify stIdentify = { 0, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, AppTask::TriggerIdentifyEffectHandler }; @@ -129,11 +155,6 @@ int AppTask::StartAppTask() return ret; } -void uiLocking(void); -void uiLocked(void); -void uiUnlocking(void); -void uiUnlocked(void); - // Identify take action void identify_TakeAction(void) { @@ -152,6 +173,45 @@ void identify_StopAction(void) #endif // LED_ENABLE } +void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEConnectionEstablished: + PLAT_LOG("CHIPoBLE connection established"); + break; + + case DeviceEventType::kCHIPoBLEConnectionClosed: + PLAT_LOG("CHIPoBLE disconnected"); + break; + + case DeviceEventType::kCommissioningComplete: + PLAT_LOG("Commissioning complete"); + break; + case DeviceEventType::kThreadStateChange: + PLAT_LOG("Thread State Change"); + bool isThreadAttached = ThreadStackMgrImpl().IsThreadAttached(); + + if (isThreadAttached) + { + PLAT_LOG("Device is on the Thread Network"); +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + if (isAppStarting) + { + StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); + isAppStarting = false; + } +#endif + } + break; + } +} + +void OTAInitTimerEventHandler(TimerHandle_t xTimer) +{ + InitializeOTARequestor(); +} + int AppTask::Init() { cc13xx_26xxLogInit(); @@ -159,6 +219,9 @@ int AppTask::Init() // Init Chip memory management before the stack Platform::MemoryInit(); + PLAT_LOG("Software Version: %d", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION); + PLAT_LOG("Software Version String: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); + CHIP_ERROR ret = PlatformMgr().InitChipStack(); if (ret != CHIP_NO_ERROR) { @@ -167,6 +230,23 @@ int AppTask::Init() ; } + // Create FreeRTOS sw timer for OTA timer. + sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel + OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = light obj context + OTAInitTimerEventHandler // timer callback handler + ); + + if (sOTAInitTimer == NULL) + { + PLAT_LOG("sOTAInitTimer timer create failed"); + } + else + { + PLAT_LOG("sOTAInitTimer timer created successfully "); + } + ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) { @@ -189,14 +269,6 @@ int AppTask::Init() ; } - ret = PlatformMgr().StartEventLoopTask(); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); - while (1) - ; - } - ret = ThreadStackMgrImpl().StartThreadTask(); if (ret != CHIP_NO_ERROR) { @@ -221,6 +293,9 @@ int AppTask::Init() // Init ZCL Data Model and start server PLAT_LOG("Initialize Server"); static CommonCaseDeviceServerInitParams initParams; + static DefaultTestEventTriggerDelegate sTestEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); // Initialize info provider @@ -229,8 +304,18 @@ int AppTask::Init() Server::GetInstance().Init(initParams); + ret = PlatformMgr().StartEventLoopTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); + while (1) + ; + } + uiInit(); + PlatformMgr().AddEventHandler(DeviceEventCallback, reinterpret_cast(nullptr)); + PlatformMgr().LockChipStack(); { uint8_t numberOfCredentialsPerUser = 0; @@ -299,9 +384,16 @@ int AppTask::Init() ConfigurationMgr().LogDeviceConfig(); + bool isThreadEnabled = ThreadStackMgrImpl().IsThreadEnabled(); + if (!isThreadEnabled && isAppStarting) + { #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - InitializeOTARequestor(); + PLAT_LOG("Thread is Disabled, enable OTA Requestor"); + StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); + isAppStarting = false; #endif + } + // QR code will be used with CHIP Tool PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE)); @@ -326,6 +418,32 @@ void AppTask::AppTaskMain(void * pvParameter) } } +void StartTimer(uint32_t aTimeoutMs) +{ + PLAT_LOG("Start OTA Init Timer") + if (xTimerIsTimerActive(sOTAInitTimer)) + { + PLAT_LOG("app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sOTAInitTimer, pdMS_TO_TICKS(aTimeoutMs), 100) != pdPASS) + { + PLAT_LOG("sOTAInitTimer timer start() failed"); + } +} + +void CancelTimer(void) +{ + if (xTimerStop(sOTAInitTimer, 0) == pdFAIL) + { + PLAT_LOG("sOTAInitTimer stop() failed"); + } +} + void AppTask::ActionInitiated(LockManager::Action_t aAction) { if (aAction == LockManager::LOCK_ACTION) @@ -426,7 +544,6 @@ void AppTask::DispatchEvent(AppEvent * aEvent) } } break; - case AppEvent::kEventType_IdentifyStart: identify_TakeAction(); PLAT_LOG("Identify started"); @@ -436,7 +553,6 @@ void AppTask::DispatchEvent(AppEvent * aEvent) identify_StopAction(); PLAT_LOG("Identify stopped"); break; - case AppEvent::kEventType_AppEvent: if (NULL != aEvent->Handler) { diff --git a/examples/platform/cc13x4_26x4/project_include/OpenThreadConfig.h b/examples/platform/cc13x4_26x4/project_include/OpenThreadConfig.h index c4087578b982c8..f1a569e012e4de 100644 --- a/examples/platform/cc13x4_26x4/project_include/OpenThreadConfig.h +++ b/examples/platform/cc13x4_26x4/project_include/OpenThreadConfig.h @@ -23,30 +23,6 @@ #pragma once -#define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 22 -#define OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 0 -#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 0 -#define OPENTHREAD_CONFIG_DIAG_ENABLE 0 -#define OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE 0 -#define OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE 1 -#define OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE 1 -#define OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 1 -#define OPENTHREAD_CONFIG_MAC_FILTER_ENABLE 0 - -#define OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD 6 - -// TCP disabled until OpenThread has a GN/Ninja build for the tcplp library -#define OPENTHREAD_CONFIG_TCP_ENABLE 0 -#define OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS 0 -#define OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE 0 -#define OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE 0 -#define OPENTHREAD_CONFIG_COMMISSIONER_ENABLE 0 -#define OPENTHREAD_CONFIG_JOINER_ENABLE 0 -#define UART_AS_SERIAL_TRANSPORT 1 -#ifdef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE -#undef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE -#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 0 -#endif #define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_APP // Use the TI-supplied default platform configuration for remainder #ifdef OPENTHREAD_PROJECT_CORE_CONFIG_FILE diff --git a/examples/pump-app/cc13x4_26x4/BUILD.gn b/examples/pump-app/cc13x4_26x4/BUILD.gn index 1429379e2bedb3..853b88288424aa 100644 --- a/examples/pump-app/cc13x4_26x4/BUILD.gn +++ b/examples/pump-app/cc13x4_26x4/BUILD.gn @@ -63,6 +63,7 @@ ti_simplelink_executable("pump_app") { output_name = "chip-${ti_simplelink_board}-pump-example.out" sources = [ + "${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerHandler.cpp", "${project_dir}/main/AppTask.cpp", "${project_dir}/main/CHIPDeviceManager.cpp", "${project_dir}/main/DeviceCallbacks.cpp", @@ -71,6 +72,10 @@ ti_simplelink_executable("pump_app") { "${project_dir}/main/main.cpp", ] + public = [ + "${chip_root}/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.h", + ] + deps = [ ":sdk", ":sysconfig", diff --git a/examples/pump-app/cc13x4_26x4/README.md b/examples/pump-app/cc13x4_26x4/README.md index 9c46aa697263ce..1e7e0c33b2136a 100644 --- a/examples/pump-app/cc13x4_26x4/README.md +++ b/examples/pump-app/cc13x4_26x4/README.md @@ -64,10 +64,16 @@ guide assumes that the environment is linux based, and recommends Ubuntu 20.04. ``` - Run the bootstrap script to setup the build environment. +- Note, a recursive submodule checkout is required to utilize TI's Openthread + reference commit. +- Note, in order to build the chip-tool and ota-provider examples, a recursive + submodule checkout is required for the linux platform as seen in the command + below. ``` $ cd ~/connectedhomeip $ source ./scripts/bootstrap.sh + $ ./scripts/checkout_submodules.py --shallow --platform cc13xx_26xx linux --recursive ``` diff --git a/examples/pump-app/cc13x4_26x4/args.gni b/examples/pump-app/cc13x4_26x4/args.gni index a1018dafc1f370..b14472acfe551d 100644 --- a/examples/pump-app/cc13x4_26x4/args.gni +++ b/examples/pump-app/cc13x4_26x4/args.gni @@ -33,7 +33,11 @@ chip_enable_ota_requestor = true ot_ti_lib_dir = "" openthread_external_platform = "${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti" -chip_openthread_target = "" + +# When using TI Certified Openthread libs set to ${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert +# For source builds, set to empty string. +chip_openthread_target = + "${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert" chip_openthread_ftd = true @@ -62,3 +66,8 @@ chip_persist_subscriptions = false chip_subscription_timeout_resumption = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" + +if (chip_openthread_target != "") { + openthread_root = + "//third_party/connectedhomeip/third_party/openthread/ot-ti/openthread" +} diff --git a/examples/pump-app/cc13x4_26x4/chip.syscfg b/examples/pump-app/cc13x4_26x4/chip.syscfg index e4ae2b6acfbbd2..16ce3520e42674 100644 --- a/examples/pump-app/cc13x4_26x4/chip.syscfg +++ b/examples/pump-app/cc13x4_26x4/chip.syscfg @@ -89,8 +89,8 @@ CCFG.enableCodeGeneration = false; /* NVS */ NVS1.$name = "CONFIG_NVSINTERNAL"; -NVS1.internalFlash.regionBase = 0xFB800; -NVS1.internalFlash.regionSize = 0x2800; +NVS1.internalFlash.regionBase = 0xF8800; +NVS1.internalFlash.regionSize = 0x6000; NVS2.$name = "CONFIG_NVSEXTERNAL"; diff --git a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp index 0aaa1c6b4029a7..9ec109313d3ad1 100644 --- a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp @@ -49,6 +49,10 @@ #include +#include +#include +#include + #include #include @@ -70,6 +74,8 @@ #endif #define BUTTON_ENABLE 1 +#define OTAREQUESTOR_INIT_TIMER_DELAY_MS 10000 + using namespace chip; using namespace chip::app; using namespace chip::Credentials; @@ -90,6 +96,12 @@ AppTask AppTask::sAppTask; static DeviceCallbacks sDeviceCallbacks; +void StartTimer(uint32_t aTimeoutMs); +void CancelTimer(void); + +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR static DefaultOTARequestor sRequestorCore; static DefaultOTARequestorStorage sRequestorStorage; @@ -110,12 +122,60 @@ void InitializeOTARequestor(void) } #endif +TimerHandle_t sOTAInitTimer = 0; + +// The OTA Init Timer is only started upon the first Thread State Change +// detected if the device is already on a Thread Network, or during the AppTask +// Init sequence if the device is not yet on a Thread Network. Once the timer +// has been started once, it does not need to be started again so the flag will +// be set to false. +bool isAppStarting = true; + static const chip::EndpointId sIdentifyEndpointId = 0; static const uint32_t sIdentifyBlinkRateMs = 500; ::Identify stIdentify = { sIdentifyEndpointId, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, AppTask::TriggerIdentifyEffectHandler }; +void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEConnectionEstablished: + PLAT_LOG("CHIPoBLE connection established"); + break; + + case DeviceEventType::kCHIPoBLEConnectionClosed: + PLAT_LOG("CHIPoBLE disconnected"); + break; + + case DeviceEventType::kCommissioningComplete: + PLAT_LOG("Commissioning complete"); + break; + case DeviceEventType::kThreadStateChange: + PLAT_LOG("Thread State Change"); + bool isThreadAttached = ThreadStackMgrImpl().IsThreadAttached(); + + if (isThreadAttached) + { + PLAT_LOG("Device is on the Thread Network"); +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + if (isAppStarting) + { + StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); + isAppStarting = false; + } +#endif + } + break; + } +} + +void OTAInitTimerEventHandler(TimerHandle_t xTimer) +{ + InitializeOTARequestor(); +} + int AppTask::StartAppTask() { int ret = 0; @@ -146,6 +206,9 @@ int AppTask::Init() // Init Chip memory management before the stack Platform::MemoryInit(); + PLAT_LOG("Software Version: %d", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION); + PLAT_LOG("Software Version String: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); + CHIP_ERROR ret = PlatformMgr().InitChipStack(); if (ret != CHIP_NO_ERROR) { @@ -154,6 +217,23 @@ int AppTask::Init() ; } + // Create FreeRTOS sw timer for OTA timer. + sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel + OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = light obj context + OTAInitTimerEventHandler // timer callback handler + ); + + if (sOTAInitTimer == NULL) + { + PLAT_LOG("sOTAInitTimer timer create failed"); + } + else + { + PLAT_LOG("sOTAInitTimer timer created successfully "); + } + ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) { @@ -185,6 +265,8 @@ int AppTask::Init() ; } + PlatformMgr().AddEventHandler(DeviceEventCallback, reinterpret_cast(nullptr)); + uiInit(); // Initialize device attestation config @@ -211,15 +293,26 @@ int AppTask::Init() #endif // Init ZCL Data Model - static chip::CommonCaseDeviceServerInitParams initParams; + PLAT_LOG("Initialize Server"); + static CommonCaseDeviceServerInitParams initParams; + static DefaultTestEventTriggerDelegate sTestEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + chip::Server::GetInstance().Init(initParams); ConfigurationMgr().LogDeviceConfig(); + bool isThreadEnabled = ThreadStackMgrImpl().IsThreadEnabled(); + if (!isThreadEnabled && isAppStarting) + { #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - InitializeOTARequestor(); + PLAT_LOG("Thread is Disabled, enable OTA Requestor"); + StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); + isAppStarting = false; #endif + } // QR code will be used with CHIP Tool PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE)); @@ -260,6 +353,32 @@ void AppTask::PostEvent(const AppEvent * aEvent) } } +void StartTimer(uint32_t aTimeoutMs) +{ + PLAT_LOG("Start OTA Init Timer") + if (xTimerIsTimerActive(sOTAInitTimer)) + { + PLAT_LOG("app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sOTAInitTimer, pdMS_TO_TICKS(aTimeoutMs), 100) != pdPASS) + { + PLAT_LOG("sOTAInitTimer timer start() failed"); + } +} + +void CancelTimer(void) +{ + if (xTimerStop(sOTAInitTimer, 0) == pdFAIL) + { + PLAT_LOG("sOTAInitTimer stop() failed"); + } +} + void AppTask::ActionInitiated(PumpManager::Action_t aAction, int32_t aActor) { // If the action has been initiated by the pump, update the pump trait @@ -363,7 +482,7 @@ void AppTask::DispatchEvent(AppEvent * aEvent) PLAT_LOG("Disabled BLE Advertisements"); } } - else if (AppEvent::kAppEventButtonType_LongPressed == aEvent->ButtonEvent.Type) + else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) { chip::Server::GetInstance().ScheduleFactoryReset(); } diff --git a/examples/pump-app/cc13x4_26x4/main/include/AppEvent.h b/examples/pump-app/cc13x4_26x4/main/include/AppEvent.h index 3a9c606e95c330..cd5017a3bee60d 100644 --- a/examples/pump-app/cc13x4_26x4/main/include/AppEvent.h +++ b/examples/pump-app/cc13x4_26x4/main/include/AppEvent.h @@ -39,7 +39,6 @@ struct AppEvent kAppEventButtonType_None = 0, kAppEventButtonType_Clicked, kAppEventButtonType_LongClicked, - kAppEventButtonType_LongPressed, }; enum AppEventType Type; diff --git a/examples/pump-controller-app/cc13x4_26x4/BUILD.gn b/examples/pump-controller-app/cc13x4_26x4/BUILD.gn index 7227fe31adafcc..d495b6fb45b323 100644 --- a/examples/pump-controller-app/cc13x4_26x4/BUILD.gn +++ b/examples/pump-controller-app/cc13x4_26x4/BUILD.gn @@ -64,12 +64,17 @@ ti_simplelink_executable("pump_controller_app") { output_name = "chip-${ti_simplelink_board}-pump-controller-example.out" sources = [ + "${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerHandler.cpp", "${project_dir}/main/AppTask.cpp", "${project_dir}/main/PumpManager.cpp", "${project_dir}/main/ZclCallbacks.cpp", "${project_dir}/main/main.cpp", ] + public = [ + "${chip_root}/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.h", + ] + deps = [ ":sdk", ":sysconfig", diff --git a/examples/pump-controller-app/cc13x4_26x4/README.md b/examples/pump-controller-app/cc13x4_26x4/README.md index bff60fdd3b1169..bd357fb25f2961 100644 --- a/examples/pump-controller-app/cc13x4_26x4/README.md +++ b/examples/pump-controller-app/cc13x4_26x4/README.md @@ -65,10 +65,16 @@ guide assumes that the environment is linux based, and recommends Ubuntu 20.04. ``` - Run the bootstrap script to setup the build environment. +- Note, a recursive submodule checkout is required to utilize TI's Openthread + reference commit. +- Note, in order to build the chip-tool and ota-provider examples, a recursive + submodule checkout is required for the linux platform as seen in the command + below. ``` $ cd ~/connectedhomeip $ source ./scripts/bootstrap.sh + $ ./scripts/checkout_submodules.py --shallow --platform cc13xx_26xx linux --recursive ``` @@ -82,6 +88,7 @@ Ninja to build the executable. ``` $ cd ~/connectedhomeip $ source ./scripts/activate.sh + $ ./scripts/checkout_submodules.py --shallow --platform cc13xx_26xx --recursive ``` @@ -247,7 +254,7 @@ Commissioning complete, notify platform driver to persist network credentials. Read generic vendor name from Basic cluster ``` -./chip-tool basic read vendor-name 1 0 +./chip-tool basicinformation read vendor-name 1 0 ``` ### Provisioning diff --git a/examples/pump-controller-app/cc13x4_26x4/args.gni b/examples/pump-controller-app/cc13x4_26x4/args.gni index dbbc3cd09f6b7e..d6af087119dfe5 100644 --- a/examples/pump-controller-app/cc13x4_26x4/args.gni +++ b/examples/pump-controller-app/cc13x4_26x4/args.gni @@ -33,7 +33,11 @@ chip_enable_ota_requestor = true ot_ti_lib_dir = "" openthread_external_platform = "${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti" -chip_openthread_target = "" + +# When using TI Certified Openthread libs set to ${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert +# For source builds, set to empty string. +chip_openthread_target = + "${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert" chip_openthread_ftd = true @@ -62,3 +66,8 @@ chip_persist_subscriptions = false chip_subscription_timeout_resumption = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" + +if (chip_openthread_target != "") { + openthread_root = + "//third_party/connectedhomeip/third_party/openthread/ot-ti/openthread" +} diff --git a/examples/pump-controller-app/cc13x4_26x4/chip.syscfg b/examples/pump-controller-app/cc13x4_26x4/chip.syscfg index d0cdc696f0e832..81271837d1511d 100644 --- a/examples/pump-controller-app/cc13x4_26x4/chip.syscfg +++ b/examples/pump-controller-app/cc13x4_26x4/chip.syscfg @@ -89,8 +89,8 @@ CCFG.enableCodeGeneration = false; /* NVS */ NVS1.$name = "CONFIG_NVSINTERNAL"; -NVS1.internalFlash.regionBase = 0xFB800; -NVS1.internalFlash.regionSize = 0x2800; +NVS1.internalFlash.regionBase = 0xF8800; +NVS1.internalFlash.regionSize = 0x6000; NVS2.$name = "CONFIG_NVSEXTERNAL"; diff --git a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp index fd44a3df454b57..a8d1e1d88f5cd3 100644 --- a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp @@ -44,6 +44,10 @@ #include +#include +#include +#include + #include #include @@ -61,6 +65,8 @@ #endif #define BUTTON_ENABLE 1 +#define OTAREQUESTOR_INIT_TIMER_DELAY_MS 10000 + using namespace ::chip; using namespace ::chip::app; using namespace ::chip::Credentials; @@ -77,6 +83,12 @@ static Button_Handle sAppRightHandle; AppTask AppTask::sAppTask; +void StartTimer(uint32_t aTimeoutMs); +void CancelTimer(void); + +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR static DefaultOTARequestor sRequestorCore; static DefaultOTARequestorStorage sRequestorStorage; @@ -97,6 +109,15 @@ void InitializeOTARequestor(void) } #endif +TimerHandle_t sOTAInitTimer = 0; + +// The OTA Init Timer is only started upon the first Thread State Change +// detected if the device is already on a Thread Network, or during the AppTask +// Init sequence if the device is not yet on a Thread Network. Once the timer +// has been started once, it does not need to be started again so the flag will +// be set to false. +bool isAppStarting = true; + static const chip::EndpointId sIdentifyEndpointId = 0; static const uint32_t sIdentifyBlinkRateMs = 500; @@ -144,6 +165,45 @@ void identify_StopAction(void) #endif // LED_ENABLE } +void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEConnectionEstablished: + PLAT_LOG("CHIPoBLE connection established"); + break; + + case DeviceEventType::kCHIPoBLEConnectionClosed: + PLAT_LOG("CHIPoBLE disconnected"); + break; + + case DeviceEventType::kCommissioningComplete: + PLAT_LOG("Commissioning complete"); + break; + case DeviceEventType::kThreadStateChange: + PLAT_LOG("Thread State Change"); + bool isThreadAttached = ThreadStackMgrImpl().IsThreadAttached(); + + if (isThreadAttached) + { + PLAT_LOG("Device is on the Thread Network"); +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + if (isAppStarting) + { + StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); + isAppStarting = false; + } +#endif + } + break; + } +} + +void OTAInitTimerEventHandler(TimerHandle_t xTimer) +{ + InitializeOTARequestor(); +} + int AppTask::Init() { cc13xx_26xxLogInit(); @@ -151,6 +211,9 @@ int AppTask::Init() // Init Chip memory management before the stack chip::Platform::MemoryInit(); + PLAT_LOG("Software Version: %d", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION); + PLAT_LOG("Software Version String: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); + CHIP_ERROR ret = PlatformMgr().InitChipStack(); if (ret != CHIP_NO_ERROR) { @@ -159,6 +222,23 @@ int AppTask::Init() ; } + // Create FreeRTOS sw timer for OTA timer. + sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel + OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = light obj context + OTAInitTimerEventHandler // timer callback handler + ); + + if (sOTAInitTimer == NULL) + { + PLAT_LOG("sOTAInitTimer timer create failed"); + } + else + { + PLAT_LOG("sOTAInitTimer timer created successfully "); + } + ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) { @@ -182,14 +262,6 @@ int AppTask::Init() ; } - ret = PlatformMgr().StartEventLoopTask(); - if (ret != CHIP_NO_ERROR) - { - PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); - while (true) - ; - } - ret = ThreadStackMgrImpl().StartThreadTask(); if (ret != CHIP_NO_ERROR) { @@ -214,9 +286,22 @@ int AppTask::Init() // Init ZCL Data Model and start server PLAT_LOG("Initialize Server"); static chip::CommonCaseDeviceServerInitParams initParams; + static DefaultTestEventTriggerDelegate sTestEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); chip::Server::GetInstance().Init(initParams); + ret = PlatformMgr().StartEventLoopTask(); + if (ret != CHIP_NO_ERROR) + { + PLAT_LOG("PlatformMgr().StartEventLoopTask() failed"); + while (true) + ; + } + + PlatformMgr().AddEventHandler(DeviceEventCallback, reinterpret_cast(nullptr)); + uiInit(); // Initialize Pump module @@ -227,9 +312,15 @@ int AppTask::Init() ConfigurationMgr().LogDeviceConfig(); + bool isThreadEnabled = ThreadStackMgrImpl().IsThreadEnabled(); + if (!isThreadEnabled && isAppStarting) + { #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR - InitializeOTARequestor(); + PLAT_LOG("Thread is Disabled, enable OTA Requestor"); + StartTimer(OTAREQUESTOR_INIT_TIMER_DELAY_MS); + isAppStarting = false; #endif + } // QR code will be used with CHIP Tool PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); @@ -261,6 +352,32 @@ void AppTask::PostEvent(const AppEvent * aEvent) } } +void StartTimer(uint32_t aTimeoutMs) +{ + PLAT_LOG("Start OTA Init Timer") + if (xTimerIsTimerActive(sOTAInitTimer)) + { + PLAT_LOG("app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sOTAInitTimer, pdMS_TO_TICKS(aTimeoutMs), 100) != pdPASS) + { + PLAT_LOG("sOTAInitTimer timer start() failed"); + } +} + +void CancelTimer(void) +{ + if (xTimerStop(sOTAInitTimer, 0) == pdFAIL) + { + PLAT_LOG("sOTAInitTimer stop() failed"); + } +} + void AppTask::ActionInitiated(PumpManager::Action_t aAction, int32_t aActor) { // If the action has been initiated by the pump, update the pump trait @@ -355,7 +472,7 @@ void AppTask::DispatchEvent(AppEvent * aEvent) PLAT_LOG("Disabled BLE Advertisements"); } } - else if (AppEvent::kAppEventButtonType_LongPressed == aEvent->ButtonEvent.Type) + else if (AppEvent::kAppEventButtonType_LongClicked == aEvent->ButtonEvent.Type) { chip::Server::GetInstance().ScheduleFactoryReset(); } diff --git a/examples/pump-controller-app/cc13x4_26x4/main/include/AppEvent.h b/examples/pump-controller-app/cc13x4_26x4/main/include/AppEvent.h index 3a9c606e95c330..cd5017a3bee60d 100644 --- a/examples/pump-controller-app/cc13x4_26x4/main/include/AppEvent.h +++ b/examples/pump-controller-app/cc13x4_26x4/main/include/AppEvent.h @@ -39,7 +39,6 @@ struct AppEvent kAppEventButtonType_None = 0, kAppEventButtonType_Clicked, kAppEventButtonType_LongClicked, - kAppEventButtonType_LongPressed, }; enum AppEventType Type; diff --git a/examples/shell/cc13x4_26x4/README.md b/examples/shell/cc13x4_26x4/README.md index d3a6bc9374f83b..3f1923f3db33af 100644 --- a/examples/shell/cc13x4_26x4/README.md +++ b/examples/shell/cc13x4_26x4/README.md @@ -22,10 +22,13 @@ guide assumes that the environment is linux based, and recommends Ubuntu 20.04. ``` - Run the bootstrap script to setup the build environment. +- Note, a recursive submodule checkout is required to utilize TI's Openthread + reference commit. ``` $ cd ~/connectedhomeip $ source ./scripts/bootstrap.sh + $ ./scripts/checkout_submodules.py --shallow --platform cc13xx_26xx --recursive ``` diff --git a/examples/shell/cc13x4_26x4/args.gni b/examples/shell/cc13x4_26x4/args.gni index 631165271a0399..2fd57c3a580f69 100644 --- a/examples/shell/cc13x4_26x4/args.gni +++ b/examples/shell/cc13x4_26x4/args.gni @@ -32,7 +32,11 @@ chip_enable_ota_requestor = true chip_openthread_ftd = false openthread_external_platform = "${chip_root}/third_party/openthread/platforms/ti:libopenthread-ti" -chip_openthread_target = "" + +# When using TI Certified Openthread libs set to ${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert +# For source builds, set to empty string. +chip_openthread_target = + "${chip_root}/third_party/openthread/platforms/ti:ot-ti-cert" # Disable CHIP Logging chip_progress_logging = false @@ -61,3 +65,8 @@ chip_persist_subscriptions = false chip_subscription_timeout_resumption = false freertos_root = "//third_party/connectedhomeip/third_party/ti_simplelink_sdk/repo_cc13xx_cc26xx/source/third_party/freertos" + +if (chip_openthread_target != "") { + openthread_root = + "//third_party/connectedhomeip/third_party/openthread/ot-ti/openthread" +} diff --git a/examples/shell/cc13x4_26x4/chip.syscfg b/examples/shell/cc13x4_26x4/chip.syscfg index 725bac1377a875..6f4e021d328709 100644 --- a/examples/shell/cc13x4_26x4/chip.syscfg +++ b/examples/shell/cc13x4_26x4/chip.syscfg @@ -89,8 +89,8 @@ CCFG.enableCodeGeneration = false; /* NVS */ NVS1.$name = "CONFIG_NVSINTERNAL"; -NVS1.internalFlash.regionBase = 0xFB800; -NVS1.internalFlash.regionSize = 0x2800; +NVS1.internalFlash.regionBase = 0xF8800; +NVS1.internalFlash.regionSize = 0x6000; NVS2.$name = "CONFIG_NVSEXTERNAL"; diff --git a/examples/shell/cc13x4_26x4/main/AppTask.cpp b/examples/shell/cc13x4_26x4/main/AppTask.cpp index 83684b0fbcd592..86432279d5c8ad 100644 --- a/examples/shell/cc13x4_26x4/main/AppTask.cpp +++ b/examples/shell/cc13x4_26x4/main/AppTask.cpp @@ -136,13 +136,6 @@ CHIP_ERROR AppTask::Init() ; } - ret = PlatformMgr().StartEventLoopTask(); - if (ret != CHIP_NO_ERROR) - { - while (true) - ; - } - ret = ThreadStackMgrImpl().StartThreadTask(); if (ret != CHIP_NO_ERROR) { @@ -168,6 +161,13 @@ CHIP_ERROR AppTask::Init() (void) initParams.InitializeStaticResourcesBeforeServerInit(); chip::Server::GetInstance().Init(initParams); + ret = PlatformMgr().StartEventLoopTask(); + if (ret != CHIP_NO_ERROR) + { + while (true) + ; + } + #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR InitializeOTARequestor(); #endif diff --git a/src/platform/cc13xx_26xx/BLEManagerImpl.cpp b/src/platform/cc13xx_26xx/BLEManagerImpl.cpp index 912db7c6f81f57..7cc761f16d3b35 100644 --- a/src/platform/cc13xx_26xx/BLEManagerImpl.cpp +++ b/src/platform/cc13xx_26xx/BLEManagerImpl.cpp @@ -557,7 +557,7 @@ void BLEManagerImpl::EventHandler_init(void) CHIPoBLEProfile_AddService(GATT_ALL_SERVICES); // Start Bond Manager and register callback - VOID GAPBondMgr_Register(BLEMgr_BondMgrCBs); + VOID GAPBondMgr_Register(&BLEMgr_BondMgrCBs); // Register with GAP for HCI/Host messages. This is needed to receive HCI // events. For more information, see the HCI section in the User's Guide: @@ -950,9 +950,6 @@ void BLEManagerImpl::ProcessEvtHdrMsg(QueuedEvt_t * pMsg) case PAIR_STATE_EVT: { BLEMGR_LOG("BLEMGR: PAIR_STATE_EVT"); - - // Send passcode response - GAPBondMgr_PasscodeRsp(((PasscodeData_t *) (pMsg->pData))->connHandle, SUCCESS, B_APP_DEFAULT_PASSCODE); } break; diff --git a/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.cpp b/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.cpp new file mode 100644 index 00000000000000..69935bb024559d --- /dev/null +++ b/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.cpp @@ -0,0 +1,31 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DefaultTestEventTriggerDelegate.h" + +#include +#include + +namespace chip { + +bool DefaultTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const +{ + return !mEnableKey.empty() && mEnableKey.data_equal(enableKey); +} + +} // namespace chip diff --git a/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.h b/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.h new file mode 100644 index 00000000000000..0bfd4c5b0fa725 --- /dev/null +++ b/src/platform/cc13xx_26xx/DefaultTestEventTriggerDelegate.h @@ -0,0 +1,36 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { + +class DefaultTestEventTriggerDelegate : public TestEventTriggerDelegate +{ +public: + explicit DefaultTestEventTriggerDelegate(const ByteSpan & enableKey) : mEnableKey(enableKey) {} + + bool DoesEnableKeyMatch(const ByteSpan & enableKey) const override; + +private: + ByteSpan mEnableKey; +}; + +} // namespace chip diff --git a/src/platform/cc13xx_26xx/ThreadStackManagerImpl.cpp b/src/platform/cc13xx_26xx/ThreadStackManagerImpl.cpp index 46cb487eece86f..98855b5ea7037f 100644 --- a/src/platform/cc13xx_26xx/ThreadStackManagerImpl.cpp +++ b/src/platform/cc13xx_26xx/ThreadStackManagerImpl.cpp @@ -204,6 +204,16 @@ void ThreadStackManagerImpl::GetExtAddress(otExtAddress & aExtAddr) memcpy(aExtAddr.m8, extAddr->m8, OT_EXT_ADDRESS_SIZE); } +bool ThreadStackManagerImpl::IsThreadAttached() +{ + return _IsThreadAttached(); +} + +bool ThreadStackManagerImpl::IsThreadEnabled() +{ + return _IsThreadEnabled(); +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/cc13xx_26xx/cc13x4_26x4/BUILD.gn b/src/platform/cc13xx_26xx/cc13x4_26x4/BUILD.gn index 0684d4eec8cde2..8fc4e76daaf6d4 100644 --- a/src/platform/cc13xx_26xx/cc13x4_26x4/BUILD.gn +++ b/src/platform/cc13xx_26xx/cc13x4_26x4/BUILD.gn @@ -32,6 +32,8 @@ static_library("cc13x4_26x4") { "../CC13XX_26XXConfig.h", "../ConfigurationManagerImpl.cpp", "../ConnectivityManagerImpl.cpp", + "../DefaultTestEventTriggerDelegate.cpp", + "../DefaultTestEventTriggerDelegate.h", "../DiagnosticDataProviderImpl.cpp", "../DiagnosticDataProviderImpl.h", "../KeyValueStoreManagerImpl.cpp", @@ -56,6 +58,7 @@ static_library("cc13x4_26x4") { ] public_deps = [ + "${chip_root}/src/app:test-event-trigger", "${chip_root}/src/crypto", "${chip_root}/src/platform:platform_base", ] diff --git a/src/platform/cc13xx_26xx/cc13x4_26x4/OTAImageProcessorImpl.cpp b/src/platform/cc13xx_26xx/cc13x4_26x4/OTAImageProcessorImpl.cpp index 94e5a2295aaaf7..060e2d5f7a2397 100644 --- a/src/platform/cc13xx_26xx/cc13x4_26x4/OTAImageProcessorImpl.cpp +++ b/src/platform/cc13xx_26xx/cc13x4_26x4/OTAImageProcessorImpl.cpp @@ -103,8 +103,7 @@ bool OTAImageProcessorImpl::IsFirstImageRun() requestor = GetRequestorInstance(); - return (requestor->GetTargetVersion() == runningSwVer) && - (requestor->GetCurrentUpdateState() == chip::app::Clusters::OtaSoftwareUpdateRequestor::OTAUpdateStateEnum::kApplying); + return (requestor->GetCurrentUpdateState() == chip::app::Clusters::OtaSoftwareUpdateRequestor::OTAUpdateStateEnum::kApplying); } /* makes room for the new block if needed */ @@ -167,7 +166,7 @@ static bool writeExtFlashImgPages(NVS_Handle handle, ssize_t offset, MutableByte } /* Erase the MCUBoot slot */ -#define BOOT_SLOT_SIZE (0x000F6000) /* must match flash_map_backend */ +#define BOOT_SLOT_SIZE (0x000F2000) /* must match flash_map_backend */ static bool eraseExtSlot(NVS_Handle handle) { int_fast16_t status; @@ -200,6 +199,22 @@ static bool eraseExtHeader(NVS_Handle handle) CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() { + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + return CHIP_ERROR_INTERNAL; + } + + uint32_t currentVersion; + uint32_t targetVersion = requestor->GetTargetVersion(); + ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion)); + if (currentVersion != targetVersion) + { + ChipLogError(SoftwareUpdate, "Current software version = %" PRIu32 ", expected software version = %" PRIu32, currentVersion, + targetVersion); + return CHIP_ERROR_INCORRECT_STATE; + } + return CHIP_NO_ERROR; } @@ -268,6 +283,7 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context) } /* reset SoC to kick MCUBoot */ + ChipLogProgress(SoftwareUpdate, "Resetting device to kick off MCUBoot"); SysCtrlSystemReset(); } diff --git a/src/platform/cc13xx_26xx/cc13x4_26x4/ThreadStackManagerImpl.h b/src/platform/cc13xx_26xx/cc13x4_26x4/ThreadStackManagerImpl.h index dc4127d7033af1..187627794965d9 100644 --- a/src/platform/cc13xx_26xx/cc13x4_26x4/ThreadStackManagerImpl.h +++ b/src/platform/cc13xx_26xx/cc13x4_26x4/ThreadStackManagerImpl.h @@ -95,6 +95,8 @@ class ThreadStackManagerImpl final : public ThreadStackManager, void _ProcMessage(otInstance * aInstance); void GetExtAddress(otExtAddress & aExtAddr); CHIP_ERROR GetBufferInfo(void); + bool IsThreadAttached(void); + bool IsThreadEnabled(void); private: // ===== Methods that implement the ThreadStackManager abstract interface. diff --git a/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos.lds b/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos.lds index f639f640d2414d..9ffd458366aded 100644 --- a/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos.lds +++ b/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos.lds @@ -212,9 +212,9 @@ SECTIONS { /* End of executable code/data, NVS is not part of the OTA image */ PROVIDE (_flash_end_address = .); - /* 5 pages of NV Memory (0x800 each) offset by 1 page for BIM/CCFG */ + /* 12 pages of NV Memory (0x800 each) offset by 1 page for BIM/CCFG */ /*.nvs (NOLOAD) : ALIGN(0x2000) { */ - .nvs (0xFB800) (NOLOAD) : AT (0xFB800) ALIGN(0x800) { + .nvs (0xF8800) (NOLOAD) : AT (0xF8000) ALIGN(0x800) { *(.nvs) } > REGION_TEXT diff --git a/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_factory_data.lds b/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_factory_data.lds index c082497d88429e..bf614d70c718c1 100644 --- a/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_factory_data.lds +++ b/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_factory_data.lds @@ -222,9 +222,9 @@ SECTIONS { /* End of executable code/data, NVS is not part of the OTA image */ PROVIDE (_flash_end_address = .); - /* 5 pages of NV Memory (0x800 each) offset by 1 page for BIM/CCFG */ + /* 12 pages of NV Memory (0x800 each) offset by 1 page for BIM/CCFG */ /*.nvs (NOLOAD) : ALIGN(0x2000) { */ - .nvs (0xFB000) (NOLOAD) : AT (0xFB000) ALIGN(0x800) { + .nvs (0xF8800) (NOLOAD) : AT (0xF8800) ALIGN(0x800) { *(.nvs) } > REGION_TEXT diff --git a/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_ota.lds b/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_ota.lds index a28b2669b3c0b8..c212cedafbaeb1 100644 --- a/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_ota.lds +++ b/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_ota.lds @@ -28,11 +28,13 @@ MEMORY MCUBOOT_HDR (RX) : ORIGIN = 0x00006000, LENGTH = 0x00000080 FLASH (RX) : ORIGIN = 0x00006080, LENGTH = 0x000F8780 /* - * NVS is the last 5 pages of slot, this area is not erased + * NVS is the last 12 pages of slot, this area is not erased * during OTA. The slot size for the primary and secondary slots - * is therefore 0xF6000 (MCUBoot Header + all the remaining space) + * is therefore 0xF2000 (MCUBoot Header + all the remaining space + * leaves 0xF2800 of space, but the slot size needs to be divisible + * by 4k so the slot size therefore becomes 0xF2000) */ - /* FLASH_NVS (RX) : ORIGIN = 0x000FC000, LENGTH = 0x00002800 */ + /* FLASH_NVS (RX) : ORIGIN = 0x000F8800, LENGTH = 0x00006000 */ FLASH_FACTORY_DATA (R) : ORIGIN = 0x000FE800, LENGTH = 0x900 /* * Customer Configuration Area and Bootloader Backdoor configuration in @@ -231,8 +233,8 @@ SECTIONS { /* End of executable code/data, NVS is not part of the OTA image */ PROVIDE (_flash_end_address = .); - /* 5 pages of NV Memory (0x800 each) at the end of Flash */ - .nvs (0xFC000) (NOLOAD) : AT (0xFC000) ALIGN(0x800) { + /* 12 pages of NV Memory (0x800 each) at the end of Flash */ + .nvs (0xF8800) (NOLOAD) : AT (0xF8800) ALIGN(0x800) { *(.nvs) } > REGION_TEXT diff --git a/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_ota_factory_data.lds b/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_ota_factory_data.lds index 1228a3cc38d3e0..d7e9996477fd73 100644 --- a/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_ota_factory_data.lds +++ b/src/platform/cc13xx_26xx/cc13x4_26x4/cc13x4_cc26x4_freertos_ota_factory_data.lds @@ -28,11 +28,13 @@ MEMORY MCUBOOT_HDR (RX) : ORIGIN = 0x00006000, LENGTH = 0x00000080 FLASH (RX) : ORIGIN = 0x00006080, LENGTH = 0x000F8780 /* - * NVS is the last 5 pages of slot, this area is not erased + * NVS is the last 12 pages of slot, this area is not erased * during OTA. The slot size for the primary and secondary slots - * is therefore 0xF6000 (MCUBoot Header + all the remaining space) + * is therefore 0xF2000 (MCUBoot Header + all the remaining space + * leaves 0xF2800 of space, but the slot size needs to be divisible + * by 4k so the slot size therefore becomes 0xF2000) */ - /* FLASH_NVS (RX) : ORIGIN = 0x000FC000, LENGTH = 0x00002800 */ + /* FLASH_NVS (RX) : ORIGIN = 0x000F8800, LENGTH = 0x00006000 */ FLASH_FACTORY_DATA (R) : ORIGIN = 0x000FE800, LENGTH = 0x900 /* * Customer Configuration Area and Bootloader Backdoor configuration in @@ -231,8 +233,8 @@ SECTIONS { /* End of executable code/data, NVS is not part of the OTA image */ PROVIDE (_flash_end_address = .); - /* 5 pages of NV Memory (0x800 each) at the end of Flash */ - .nvs (0xFC000) (NOLOAD) : AT (0xFC000) ALIGN(0x800) { + /* 12 pages of NV Memory (0x800 each) at the end of Flash */ + .nvs (0xF8800) (NOLOAD) : AT (0xF8800) ALIGN(0x800) { *(.nvs) } > REGION_TEXT diff --git a/src/platform/cc13xx_26xx/nvocmp.c b/src/platform/cc13xx_26xx/nvocmp.c new file mode 100644 index 00000000000000..a77a28977601eb --- /dev/null +++ b/src/platform/cc13xx_26xx/nvocmp.c @@ -0,0 +1,5201 @@ +/****************************************************************************** + + @file nvocmp.c + + @brief NV driver for CC26x2 devices - On-Chip Multi-Page Flash Memory + + Group: CMCU, LPC + Target Device: cc13xx_cc26xx + + ****************************************************************************** + + Copyright (c) 2023-2024, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ****************************************************************************** + + + *****************************************************************************/ + +//***************************************************************************** +// Design Overview +//***************************************************************************** +/* +This driver implements a non-volatile (NV) memory system that utilizes multi pages +(consecutive) of on-chip Flash memory. After initialization, all pages except one +are ACTIVE and the remaining one page is available for "compaction" when the ACTIVE +pages do not have enough empty space for data write operation. Compaction can occur +'just in time' during a data write operation or 'on demand' by application request. +The compaction process is designed to survive a power cycle before it completes. It +will resume where it was interrupted and complete the process. + +This driver makes the following assumptions and uses them to optimize the code +and data storage design: (1) Flash memory is addressable at individual, 1-byte +resolution so no padding or word-alignment is necessary (2) Flash has limited +number of writes per flash 'sector' between erases. To prevent going over this +limit, "small" items are written in one operation. + +Each Flash page has a "page header" which indicates its current state, +located at the first byte of the Flash page and "compact header" which indicates +its compaction state, located following "page header". The remainder of +the Flash page contains NV data items which are packed together following the +page header and compact header. Each NV data item has two parts, (1) a data block +which is stored first (lower memory address), (2) immediately followed by item header +(higher memory address). The item header contains information necessary to traverse the +packed data items, as well as, current status of each data item. Obsolete items +marked accordingly but a search for the newest instance of an item is sped up +by starting the search at the last entry in the page (higher memory address). + +Each item is unique, addressed using three ID values (system ID, item ID, sub +ID). These three values are stored in the header along with a 'signature', a +CRC8 value, the length of the data block, and two status bits. The two status +bits indicate whether an item is still active and the health or validity of an +item. The signature byte is used by the driver to detect the presence of an +item, and is the same for all items as well as the page header and compact header. +The CRC8 value allows the driver to confirm the integrity of the items during +compaction and optionally when an item read operation is requested. The length +of the data block is used to jump from one item to the next. If this field is +corrupted, the driver is forced to search for items by signature and possibly +compute multiple CRC's to confirm it has found a valid item. Note that any +corruption event forces a compaction to recover. + +To reduce further RAM consumption, the user can define NVOCMP_RAM_OPTIMIZATION to +enable this feature. Note that for cc23x0 and cc27xx, NVOCMP_RAM_OPTIMIZATION is enabled +by default. Alternatively, if this optimization is not needed in a particular +application for cc23x0 and cc27xx, the user can define NVOCMP_NO_RAM_OPTIMIZATION to +effectively disable this feature for cc23x0 and cc27xx. + +When RAM optimization is enabled, the user can configure the size of the +working buffer by setting NVOCMP_RAM_BUFFER_SIZE, which defaults to 500. + +*/ +//***************************************************************************** +// Use / Configuration +//***************************************************************************** +/* +Since this is multi page NV driver, the number of NV pages is configurable. +NVOCMP_NVPAGES = 1 means 1 page storage and 0 compaction page. +NVOCMP_NVPAGES = 2 means 1 page storage and 1 compaction page. +NVOCMP_NVPAGES = 3 means 2 pages storage and 1 compaction page. +NVOCMP_NVPAGES = 4 means 3 pages storage and 1 compaction page. +NVOCMP_NVPAGES = 5 means 4 pages storage and 1 compaction page. +NVOCMP_NVPAGES = 6 means 5 pages storage and 1 compaction page. +NVOCMP_NVPAGES can be configured from project option. If this flag is not +configured, NVOCMP_NVPAGES = 2 will be by default. +"nvintf.h" describes the generic NV interface which is used to access NVOCMP +after initialization. Initialization is done by passing a function pointer +struct to one of NVOCMP pointer loader functions. Once this is done, the +pointer struct (which is part of the nvintf interface) should be used to call +the nvintf initialization function, which will initialize NVOCMP. At this point +NVOCMP is ready and loaded API functions can be called through the pointer +structure. Note that some pointers may be NULL depending on which NVOCMP +loader function was called. For example NVOCMP_loadApiPtrsMin() loads only +the essential functions to reduce code size at link time. +A sample code block is shown below: + +NVINTF_nvFuncts_t nvFps; +NVOCMP_loadApiPtrs(&nvFps); + +nvFps.initNV(NULL); +// Do some NV operations +nvFps.compactNV(NULL); +status = nvFps.readItem(id, 0, len, buf); + +Note: Each item operation results in a traversal of the page starting at +the most recently written item. This makes 'finding' items by 'trying' item IDs +in order extremely inefficient. The doNext() API call allows the user to find, +read, or delete items in one page traversal. However, this call requires the +user to lock access to NV until the operation is complete so it should be used +carefully and sparingly. + +Note: The compile flag NVDEBUG can be passed to enable ASSERT and ALERT +macros which provide assert and logging functionality. When this flag is used, +a printf function of the form void nvprint(char * str) MUST be +provided to link the driver. The function need not be functional, but it must +exist. NVDEBUG also exposes driver global variables for debug and testing. + +Not all user-defines (such as NVDEBUG) are supported when using NVOCMP in a +Linux environment. If debugging/logging functionality is required, the +"nv-debug" or "nv-rdwr" logging flags can be enabled in the cfg INI file. + +Configuration: +NVOCMP_STATS - Places a protected item with driver stats + +NVOCMP_CRCONREAD (on:1 off:0) - item crc is checked on read. Disabling this may +increase driver speed but safety is reduced. + +NVOCMP_NVS_INDEX - The index of the NVS_Config structure which describes the +flash sector that NVOCMP should use. Default is 0. + +NVOCMP_RECOVER_FROM_COMPACT_FAILURE - This define needs to be enabled by +the customer. It is disabled be default. When enabled, it causes the +NV driver to reformat all NV pages when there is an error while +collecting valid items for compaction. When disabled and an error +occurs while collecting valid items for compaction, NV pages will +preserve the original information prior to the start of such +operation. + +ENABLE_SANITY_CHECK - This define needs to be enabled if user needs the +NVOCMP_sanityCheckApi() to be available. This function is used to perform +a sanity check on the active partition to report if corruption has been +detected. + +NVOCMP_RAM_OPTIMIZATION - Enables RAM optimization. +NVOCMP_NO_RAM_OPTIMIZATION - Disables RAM optimization for cc23x0 and cc27xx, as it +is enabled by default on this family of devices. +NVOCMP_RAM_BUFFER_SIZE - Sets the size for the RAM buffer used when +RAM optimization is enabled. Default value is 500. + +Dependencies: +Requires NVS for NV access. +Requires TI-RTOS GateMutexPri or POSIX mutex to be enabled in configuration. +Requires API's in a crc.h to implement CRC functionality. +*/ + +//***************************************************************************** +// Includes +//***************************************************************************** + +#include +#ifdef NVOCMP_POSIX_MUTEX +#include +#elif defined(NVOCMP_POSIX_SEM) +#include +#else +#include +#endif +#include +#include +#ifndef NV_LINUX + +#include +#include + +#ifdef NVOCMP_MIN_VDD_FLASH_MV +#include +#endif +#endif + +#ifdef NV_LINUX +#include "nv_linux.h" +#endif + +//***************************************************************************** +// Constants and Definitions +//***************************************************************************** + +#define NVINTF_DONOWRAP 0x80 // Do not wrap around NV space +#define NVOCMP_FASTCP 1 // Fast Compaction by Skipping All Active Item Pages +#define NVOCMP_COMPR 0 // Order Change When Compaction +#define NVOCMP_HDRLE 0 // Little Endian Format Item Header +#define NVOCMP_FASTOFF 1 // Fast Search Offset +#define NVOCMP_FASTITEM 0 // Fast Find Item + +#ifndef NVOCMP_NWSAMEITEM +#define NVOCMP_NWSAMEITEM 0 // Not Write Same Item +#endif + +#ifndef NVOCMP_MIGRATE_ENABLED +#define NVOCMP_MIGRATE_DISABLED // Migration from old NVOCTP disabled by default +#endif + +#define NVOCMP_NVONEP 1 // One Page NV +#define NVOCMP_NVTWOP 2 // Two Page NV + +#define NVOCMP_NVSIZE NVOCMP_size +#define NVOCMP_ADDPAGE(p, n) (((p) + (n)) % NVOCMP_NVSIZE) +#define NVOCMP_INCPAGE(p) NVOCMP_ADDPAGE(p, 1) +#define NVOCMP_DECPAGE(p) NVOCMP_ADDPAGE(p, NVOCMP_NVSIZE - 1) +// Which NVS_config indice is used to initialize NVS. +#ifndef NVOCMP_NVS_INDEX +#define NVOCMP_NVS_INDEX 0 +#endif // NVOCMP_NVS_INDEX + +// Maximum ID parameters - must be coordinated with header format +#define NVOCMP_MAXSYSID 0x003F // 6 bits +#define NVOCMP_MAXITEMID 0x03FF // 10 bits +#define NVOCMP_MAXSUBID 0x03FF // 10 bits +#define NVOCMP_MAXLEN 0x0FFF // 12 bits +#define NVOCMP_INVALIDSUBID 0xFFFF // Invalid Sub Id + +// Contents of an erased Flash memory locations +#define NVOCMP_ERASEDBYTE 0xFF +#define NVOCMP_ERASEDWORD 0xFFFFFFFF + +// Size of byte +#define NVOCMP_ONEBYTE 1 + +// Compressed ID bit spacing +#define NVOCMP_CMPSPACE 12 + +// Invalid NV page - if 0xFF is ever used, change this definition +#define NVOCMP_NULLPAGE 0xFF + +// Block size for Flash-Flash XFER (Bytes) +#define NVOCMP_XFERBLKMAX 32 + +// Size in bytes of biggest item size that will be concatenated +// in RAM before write, instead of header/data written separately +#define NVOCMP_SMALLITEM 12 + +#if defined(NVOCMP_STATS) +// NV item ID for driver diagnostics +static const NVINTF_itemID_t diagId = NVOCMP_NVID_DIAG; +#endif // NVOCMP_STATS + +// CRC options +// When not NULL, reads will result in a CRC check before returning +#define NVOCMP_CRCONREAD 1 + +// findItem search types +// Find any item, item of spec'd sysid, item of spec'd sys and item id +// or find the exact item specified +enum +{ + NVOCMP_FINDANY = 0x00, + NVOCMP_FINDSYSID, + NVOCMP_FINDITMID, + NVOCMP_FINDSTRICT, + NVOCMP_FINDCONTENT = 0x10 +}; + +#define NVOCMP_FINDLMASK 0x0F +#define NVOCMP_FINDHMASK 0xF0 +//***************************************************************************** +// Macros +//***************************************************************************** + +// Makes an NV Flash address (for 0x2000 page size) +#define NVOCMP_FLASHOFFSET(pg, ofs) ((uint32_t) (((pg) << PAGE_SIZE_LSHIFT) + (ofs))) + +// Optional user provided function is called before writes/erases +// Intention is to check for sufficient voltage for operation +#ifndef NV_LINUX +#define NVOCMP_FLASHACCESS(err) \ + { \ + if (NVOCMP_voltCheckFptr) \ + { \ + if (!NVOCMP_voltCheckFptr()) \ + { \ + err = NVINTF_LOWPOWER; \ + } \ + } \ + } +#endif + +#ifdef NVOCMP_POSIX_MUTEX +// Lock driver access via TI-RTOS gatemutex +#define NVOCMP_LOCK() pthread_mutex_lock(&NVOCMP_gPosixMutex); + +// Unlock driver access via TI-RTOS gatemutex and return error code +#define NVOCMP_UNLOCK(err) \ + { \ + pthread_mutex_unlock(&NVOCMP_gPosixMutex); \ + return (err); \ + } +#elif defined(NVOCMP_POSIX_SEM) +// Lock driver access via POSIX semaphore +#define NVOCMP_LOCK() sem_wait(&NVOCMP_gPosixSem); + +// Unlock driver access via POSIX semaphore and return error code +#define NVOCMP_UNLOCK(err) \ + { \ + sem_post(&NVOCMP_gPosixSem); \ + return (err); \ + } +#else +// Lock driver access via TI-RTOS gatemutex +#define NVOCMP_LOCK() int32_t key = GateMutexPri_enter(NVOCMP_gMutexPri); + +// Unlock driver access via TI-RTOS gatemutex and return error code +#define NVOCMP_UNLOCK(err) \ + { \ + GateMutexPri_leave(NVOCMP_gMutexPri, key); \ + return (err); \ + } +#endif + +// Generate a compressed NV ID (NOTE: bit31 must be zero) +#define NVOCMP_CMPRID(s, i, b) \ + ((uint32_t) ((((((s) &NVOCMP_MAXSYSID) << NVOCMP_CMPSPACE) | ((i) &NVOCMP_MAXITEMID)) << NVOCMP_CMPSPACE) | \ + ((b) &NVOCMP_MAXSUBID))) + +// NVOCMP Unit Test Assert Macro/Function +#ifdef NVDEBUG +extern void nvprint(char * message); +extern void Main_assertHandler(uint8_t assertReason); +static void NVOCMP_assert(bool cond, char * message, bool fatal) +{ + if (!cond) + { + nvprint("NVDEBUG: "); + nvprint(message); + if (fatal) + { + Main_assertHandler(0); + } + } +} +#define NVOCMP_ASSERT(cond, message) NVOCMP_assert((cond), (message), true); +#define NVOCMP_ALERT(cond, message) NVOCMP_assert((cond), (message), false); +#define NVOCMP_ASSERT1(cond) \ + { \ + if (!cond) \ + while (1) \ + ; \ + } +#else +#ifdef NV_LINUX +#define NVOCMP_ASSERT1(cond) NVOCMP_ASSERT((cond), "NVOCMP_ASSERT1") +#else +#define NVOCMP_ASSERT(cond, message) +#define NVOCMP_ALERT(cond, message) +#define NVOCMP_ASSERT1(cond) \ + { \ + if (!cond) \ + while (1) \ + ; \ + } +#endif +#endif // NVDEBUG + +//***************************************************************************** +// Page and Header Definitions +//***************************************************************************** +#if defined(DeviceFamily_CC13X4) || defined(DeviceFamily_CC26X4) || defined(DeviceFamily_CC26X3) || \ + defined(DeviceFamily_CC23X0R5) || defined(DeviceFamily_CC23X0R2) || defined(DeviceFamily_CC27XX) +// CC26x4/CC13x4/CC23x0/cc27xx devices flash page size is (1 << 11) or 0x800 +#define PAGE_SIZE_LSHIFT 11 +#else +// CC26x2/CC13x2 devices flash page size is (1 << 13) or 0x2000 +#define PAGE_SIZE_LSHIFT 13 +#endif +#if !defined(FLASH_PAGE_SIZE) +#define FLASH_PAGE_SIZE (1 << PAGE_SIZE_LSHIFT) +#endif // FLASH_PAGE_SIZE + +#if !defined(NVOCMP_VERSION) +// Version of NV page format (do not use 0xFF) +#define NVOCMP_VERSION 0x03 +#endif // NVOCMP_VERSION + +#if !defined(NVOCMP_SIGNATURE) +// Page header validation byte (do not use 0xFF) +#define NVOCMP_SIGNATURE 0x96 +#endif // NVOCMP_SIGNATURE + +#ifndef NVOCMP_NO_RAM_OPTIMIZATION +#if defined(DeviceFamily_CC23X0R5) || defined(DeviceFamily_CC23X0R2) || defined(DeviceFamily_CC27XX) +#define NVOCMP_RAM_OPTIMIZATION +#endif +#endif + +#ifndef NVOCMP_RAM_OPTIMIZATION +// Compact Memory +#if !defined(NV_LINUX) && !defined(DeviceFamily_CC13X4) && !defined(DeviceFamily_CC26X4) && !defined(DeviceFamily_CC26X3) && \ + !defined(DeviceFamily_CC23X0R5) && !defined(DeviceFamily_CC23X0R2) && !defined(DeviceFamily_CC27XX) +#define NVOCMP_GPRAM +#endif + +#ifdef NVOCMP_GPRAM +#define RAM_BUFFER_ADDRESS (uint8_t *) GPRAM_BASE +#else +/* When CC23X0/CC27XX is used, as GPRAM is not supported, + * an SRAM buffer of FLASH_PAGE_SIZE length is declared, + * as the NVOCMP algorithm relies on it. + * Also, when CC13X4 / CC26X3 / CC26X4 is used, + * GPRAM cannot be used as it is always mapped to secure + * address space, and therefore cannot be used by non-secure + * application. A buffer in SRAM is used instead. + * */ +uint32_t tBuffer[FLASH_PAGE_SIZE >> 2]; +#endif +#else +#ifdef NVOCMP_FASTOFF +#undef NVOCMP_FASTOFF +#endif +#define NVOCMP_FASTOFF 0 + +#ifdef NVOCMP_FASTITEM +#undef NVOCMP_FASTITEM +#endif +#define NVOCMP_FASTITEM 0 + +#ifndef NVOCMP_RAM_BUFFER_SIZE +#define NVOCMP_RAM_BUFFER_SIZE 500 +#endif +uint8_t tBuffer[NVOCMP_RAM_BUFFER_SIZE]; +#endif + +// Page header structure +typedef struct +{ + uint32_t state : 8; + uint32_t cycle : 8; // Rolling page compaction count (0x00, 0xFF not used) + uint32_t allActive : 2; + uint32_t version : 6; // Version of NV page format + uint32_t signature : 8; // Signature for formatted NV page +} NVOCMP_pageHdr_t; + +typedef struct +{ + uint16_t pageOffset; + uint8_t page; + uint8_t signature; +} NVOCMP_compactHdr_t; + +// Page header size (bytes) +#define NVOCMP_PGHDRLEN (sizeof(NVOCMP_pageHdr_t)) +#define NVOCMP_COMPACTHDRLEN (sizeof(NVOCMP_compactHdr_t)) + +// Page header offsets (from 1st byte of page) +#define NVOCMP_PGHDROFS 0 +#define NVOCMP_PGHDRPST 0 // Page state +#define NVOCMP_PGHDRCYC 1 // Cycle count +#define NVOCMP_PGHDRVER 2 // Format version +#define NVOCMP_PGHDRSIG 3 // Page signature + +// Compact header offsets +#define NVOCMP_COMPMODEOFS 6 // Compact Mode Offset + +// Number of Compact headers +#define NVOCMP_NOCOMPHDR 3 + +// Page data size, offset into page +#define NVOCMP_PGDATAOFS (NVOCMP_PGHDRLEN + NVOCMP_NOCOMPHDR * NVOCMP_COMPACTHDRLEN) +#define NVOCMP_PGDATAEND (FLASH_PAGE_SIZE - 1) +#define NVOCMP_PGDATALEN (FLASH_PAGE_SIZE - NVOCMP_PGDATAOFS) + +// Page mode of operation +#define NVOCMP_PGNORMAL 0xFF // normal operation +#define NVOCMP_PGCDST 0xFE // used as compact destination +#define NVOCMP_PGCDONE 0xFC +#define NVOCMP_PGCSRC 0xF8 // used as compact source +#define NVOCMP_PGMODEBIT 0x04 + +// NVOCTP header defines +#define NVOCTP_PGACTIVE 0xA5 // Current active page +#define NVOCTP_PGXFER 0x24 // Active page being compacted +#define NVOCTP_PGDATAOFS NVOCMP_PGHDRLEN +#define NVOCTP_VERSION 0x02 +#define NVOCTP_SIGNATURE 0x96 + +// Page header state values - transitions change 1 bit in each nybble +typedef enum NVOCMP_pageState +{ + NVOCMP_PGNACT = 0xFF, + NVOCMP_PGXDST = 0xFE, + NVOCMP_PGRDY = 0x7E, + NVOCMP_PGACT = 0x7C, + NVOCMP_PGFULL = 0x78, + NVOCMP_PGXSRC = 0x70, + NVOCMP_PGNDEF = 0x00, +} NVOCMP_pageState_t; + +typedef enum NVOCMP_compactStatus +{ + NVOCMP_COMPACT_SUCCESS = 0x00, + NVOCMP_COMPACT_SRCDONE = 0x01, + NVOCMP_COMPACT_DSTDONE = 0x02, + NVOCMP_COMPACT_BOTHDOE = 0x03, + NVOCMP_COMPACT_FAILURE = 0x10, +} NVOCMP_compactStatus_t; + +// Page compaction cycle count limits (0x00 and 0xFF not used) +#define NVOCMP_MINCYCLE 0x01 // Minimum cycle count (after rollover) +#define NVOCMP_MAXCYCLE 0xFE // Maximum cycle count (before rollover) + +#define NVOCMP_ALLACTIVE 0x3 // All Items are active +#define NVOCMP_SOMEINACTIVE 0x0 // Some Items are inactive + +//***************************************************************************** +// Item Header Definitions +//***************************************************************************** + +// Item header structure +typedef struct +{ + uint32_t cmpid; // Compressed ID + uint16_t subid; // Sub ID + uint16_t itemid; // Item ID + uint8_t sysid; // System ID + uint8_t crc8; // crc byte + uint8_t sig; // signature byte + uint8_t stats; // Status 'marks' + uint16_t hofs; // Header offset + uint16_t len; // Data length + uint8_t hpage; // Header page +} NVOCMP_itemHdr_t; + +// Length (bytes) of compressed header +#define NVOCMP_ITEMHDRLEN 7 + +// Offset from beginning (low address) of header to fields in the header +#define NVOCMP_HDRSIGOFS 6 +#define NVOCMP_HDRVLDOFS 5 + +// Number of bytes in header to include in CRC calculation +#define NVOCMP_HDRCRCINC 5 + +// Compressed item header information <-- Lower Addr Higher Addr--> +// Byte: [0] [1] [2] [3] [4] [5] [6] +// Item: SSSSSSII IIIIIIII SSSSSSSS SSLLLLLL LLLLLLCC CCCCCCAV SSSSSSSS +// LSB of field: ^ ^ ^ ^ ^ +// Bit: 0 15 25 37 45 55 +// +// Bit(s) Bit Field Description +// ============================= +// 48-55: Signature byte (NVOCMP_SIGNATURE) +// 47: valid id mark (0=valid) +// 46: active id mark (1=active) +// 38-45: CRC8 value +// 26-37: data length (0-4095) +// 16-25: item sub id (0-1023) +// 6-15: nv item id (0-1023) +// 0-5: system id (0-63) + +// Bit47 in compressed header - '1' indicates 'active' NV item +// A deleted item is 'inactive' +#define NVOCMP_ACTIVEIDBIT 0x2 +// Bit46 in compressed header - '0' indicates 'valid' NV item +// A corrupted item is 'invalid' +#define NVOCMP_VALIDIDBIT 0x1 +// This bit is NOT included in the NV item itself but is encoded +// the 'stats' field of the itemHdr_t struct when the item is read +#define NVOCMP_FOLLOWBIT 0x4 + +// Index of last item header byte +#define NVOCMP_ITEMHDREND (NVOCMP_ITEMHDRLEN - 1) + +// Compressed item header byte array +typedef uint8_t cmpIH_t[NVOCMP_ITEMHDRLEN]; + +// Item write parameters +typedef struct +{ + NVOCMP_itemHdr_t * iHdr; // Ptr to item header + uint16_t dOfs; // Source data offset + uint16_t bOfs; // Buffer data offset + uint16_t len; // Buffer data length + uint8_t * pBuf; // Ptr to data buffer +} NVOCMP_itemWrp_t; + +typedef struct +{ + void * cBuf; // Pointer to content to search + uint16_t clength; // Length of content to search + uint16_t coff; // Offset content to search + void * rBuf; // Pointer to content to read + uint16_t rlength; // Length content to read +} NVOCMP_itemInfo_t; + +typedef enum NVOCMP_initAction +{ + NVOCMP_NORMAL_INIT = 0, + NVOCMP_NORMAL_RESUME, + NVOCMP_RECOVER_COMPACT, + NVOCMP_RECOVER_ERASE, + NVOCMP_FORCE_CLEAN, + NVOCMP_NORMAL_MIGRATE, + NVOCMP_ERROR_UNKNOWN, +} NVOCMP_initAction_t; + +typedef enum NVOCMP_writeMode +{ + NVOCMP_WRITE = 0, + NVOCMP_CREATE, + NVOCMP_UPDATE, +} NVOCMP_writeMode_t; + +typedef struct +{ + uint8_t state; // page state + uint8_t cycle; // page compaction cycle count. Used to select the 'newest' active page + // at device reset, in the very unlikely scenario that both pages are active. + uint8_t mode; // compact mode + uint8_t allActive; // all items are active or not + uint8_t sPage; + uint8_t ePage; + uint16_t offset; // page offset + uint16_t sOffset; + uint16_t eOffset; +} NVOCMP_pageInfo_t; + +typedef struct +{ + uint8_t xDstPage; // xdst page + uint8_t xSrcSPage; // xsrc start page + uint8_t xSrcEPage; // xsrc end page + uint8_t xSrcPages; // no of xsrc pages + uint16_t xDstOffset; // xdst offset + uint16_t xSrcSOffset; // xsrc start offset + uint16_t xSrcEOffset; // xsrc end offset +} NVOCMP_compactInfo_t; + +typedef struct +{ + uint8_t nvSize; // no of NV pages + uint8_t headPage; // head active page + uint8_t tailPage; // transfer destination page + uint8_t actPage; // current active page + uint8_t xsrcPage; // transfer source page + uint8_t forceCompact; // force compaction to happen + uint16_t actOffset; // active page offset + uint16_t xsrcOffset; // transfer source page offset + uint16_t xdstOffset; // transfer destination page offset + NVOCMP_compactInfo_t compactInfo; + NVOCMP_pageInfo_t pageInfo[NVOCMP_NVPAGES]; +} NVOCMP_nvHandle_t; +//***************************************************************************** +// Local variables +//***************************************************************************** +#define NVOCMP_NULLOFFSET 0xFFFF +#define DEFAULT_COMPACTHDR { NVOCMP_NULLOFFSET, NVOCMP_NULLPAGE, NVOCMP_SIGNATURE }; +#define THISPAGEHDR 0 +#define XSRCSTARTHDR 1 +#define XSRCENDHDR 2 +#define NVOCMP_COMPACTHDRLEN (sizeof(NVOCMP_compactHdr_t)) +// NVS Objects +#ifdef NVDEBUG +// Expose these in debug mode +NVS_Handle NVOCMP_nvsHandle; +NVS_Attrs NVOCMP_nvsAttrs; +NVOCMP_nvHandle_t NVOCMP_nvHandle; +#else +static NVS_Handle NVOCMP_nvsHandle; +static NVS_Attrs NVOCMP_nvsAttrs; + +/* The following variable has been made non-static, so it can be accessed + * through other modules through "extern". However, this is a temporary + * solution, as this variable is meant to be used only by NVOCMP. + * Users of NVOCMP must only access these features through the available + * APIs.*/ +/*static*/ NVOCMP_nvHandle_t NVOCMP_nvHandle; +#endif // NVDEBUG + +// Flag to indicate that a fatal error occurred while writing to or erasing the +// Flash memory. If flag is set, it's unsafe to attempt another write or erase. +// This flag locks writes to Flash until the next system reset. +static uint8_t NVOCMP_failF = NVINTF_NOTREADY; + +// Flag to indicate that a non-fatal error occurred while writing to or erasing +// Flash memory. With flag set, it's still safe to attempt a write or erase. +// This flag is reset by any API calls that cause an erase/write to Flash. +static uint8_t NVOCMP_failW; + +// TI-RTOS gateMutexPri for the NV driver API functions +#ifdef NVOCMP_POSIX_MUTEX +static pthread_mutex_t NVOCMP_gPosixMutex; +#elif defined(NVOCMP_POSIX_SEM) +static sem_t NVOCMP_gPosixSem; +#else +static GateMutexPri_Handle NVOCMP_gMutexPri; +#endif + +// Small NV Item Buffer, for item construction +static uint8_t NVOCMP_itemBuffer[NVOCMP_SMALLITEM]; + +// Function Pointer to an optional user provided voltage check function +static bool (*NVOCMP_voltCheckFptr)(void); +// Diagnostic counter for bad CRCs +#ifdef NVOCMP_STATS +static uint16_t NVOCMP_badCRCCount = 0; +#endif // NVOCMP_STATS + +NVOCMP_initAction_t gAction; +uint8_t NVOCMP_size; + +//***************************************************************************** +// NV API Function Prototypes +//***************************************************************************** + +static uint8_t NVOCMP_initNvApi(void * param); +static uint8_t NVOCMP_compactNvApi(uint16_t min); +static uint8_t NVOCMP_createItemApi(NVINTF_itemID_t id, uint32_t len, void * buf); +static uint8_t NVOCMP_updateItemApi(NVINTF_itemID_t id, uint32_t len, void * buf); +static uint8_t NVOCMP_deleteItemApi(NVINTF_itemID_t id); +static uint32_t NVOCMP_getItemLenApi(NVINTF_itemID_t id); +static uint8_t NVOCMP_readItemApi(NVINTF_itemID_t id, uint16_t ofs, uint16_t len, void * buf); +static uint8_t NVOCMP_readContItemApi(NVINTF_itemID_t id, uint16_t ofs, uint16_t rlen, void * rBuf, uint16_t clen, uint16_t coff, + void * cBuf, uint16_t * pSubId); +static uint8_t NVOCMP_writeItemApi(NVINTF_itemID_t id, uint16_t len, void * buf); +static uint8_t NVOCMP_doNextApi(NVINTF_nvProxy_t * prx); +static int32_t NVOCMP_lockNvApi(void); +static void NVOCMP_unlockNvApi(int32_t); +static bool NVOCMP_expectCompApi(uint16_t len); +static uint8_t NVOCMP_eraseNvApi(void); +static uint32_t NVOCMP_getFreeNvApi(void); + +#ifdef ENABLE_SANITY_CHECK +static uint32_t NVOCMP_sanityCheckApi(void); +#endif + +//***************************************************************************** +// NV Local Function Prototypes +//***************************************************************************** + +static void NVOCMP_initNv(NVOCMP_nvHandle_t * pNvHandle); +static uint8_t NVOCMP_scanPage(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, NVOCMP_pageInfo_t * pPageInfo); +static int8_t NVOCMP_findItem(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, uint16_t ofs, NVOCMP_itemHdr_t * pHdr, int8_t flag, + NVOCMP_itemInfo_t * pInfo); +static uint8_t NVOCMP_addItem(NVOCMP_nvHandle_t * pNvHandle, NVOCMP_itemHdr_t * iHdr, uint8_t * pBuf, NVOCMP_writeMode_t wm); +static void NVOCMP_writeItem(NVOCMP_nvHandle_t * pNvHandle, NVOCMP_itemHdr_t * pHdr, uint8_t dstPg, uint16_t dstOff, + uint8_t * pBuf); +static uint8_t NVOCMP_erase(NVOCMP_nvHandle_t * pNvHandle, uint8_t dstPg); +static int16_t NVOCMP_compactPage(NVOCMP_nvHandle_t * pNvHandle, uint16_t nBytes); +static NVOCMP_compactStatus_t NVOCMP_compact(NVOCMP_nvHandle_t * pNvHandle); +static uint8_t NVOCMP_getDstPage(NVOCMP_nvHandle_t * pNvHandle, uint16_t len); +static void NVOCMP_changePageState(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, NVOCMP_pageState_t state); +static void NVOCMP_setPageState(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, NVOCMP_pageState_t state); +static void NVOCMP_setItemInactive(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, uint16_t iOfs); +static uint8_t NVOCMP_readItem(NVOCMP_itemHdr_t * iHdr, uint16_t ofs, uint16_t len, void * pBuf, bool flag); +static uint8_t NVOCMP_checkItem(NVINTF_itemID_t * id, uint16_t len, NVOCMP_itemHdr_t * iHdr, uint8_t flag); +static inline void NVOCMP_read(uint8_t pg, uint16_t off, uint8_t * pBuf, uint16_t len); +static uint8_t NVOCMP_write(uint8_t dstPg, uint16_t off, uint8_t * pBuf, uint16_t len); +static void NVOCMP_readHeader(uint8_t pg, uint16_t ofs, NVOCMP_itemHdr_t * iHdr, bool flag); +static void NVOCMP_setCompactHdr(uint8_t dstPg, uint8_t pg, int16_t offset, uint16_t location); +static uint16_t NVOCMP_findOffset(uint8_t pg, uint16_t ofs); +static uint8_t NVOCMP_doNVCRC(uint8_t pg, uint16_t ofs, uint16_t len, uint8_t crc, bool flag); +static uint8_t NVOCMP_doRAMCRC(uint8_t * input, uint16_t len, uint8_t crc); +static uint8_t NVOCMP_verifyCRC(uint16_t iOfs, uint16_t len, uint8_t crc, uint8_t pg, bool flag); +static uint8_t NVOCMP_readByte(uint8_t pg, uint16_t ofs); +static void NVOCMP_writeByte(uint8_t pg, uint16_t ofs, uint8_t bwv); + +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) +static uint8_t NVOCMP_findDstPage(NVOCMP_nvHandle_t * pNvHandle); +static uint8_t NVOCMP_cleanPage(NVOCMP_nvHandle_t * pNvHandle); +static uint8_t NVOCMP_findPage(NVOCMP_pageState_t state); +static void NVOCMP_getCompactHdr(uint8_t dstPg, uint16_t location, NVOCMP_compactHdr_t * pHdr); +#endif + +#if (NVOCMP_NVPAGES > NVOCMP_NVONEP) && !defined(NVOCMP_MIGRATE_DISABLED) +static void NVOCMP_migratePage(NVOCMP_nvHandle_t * pNvHandle, uint8_t page); +#endif + +#if ((NVOCMP_NVPAGES > NVOCMP_NVONEP) && !defined(NVOCMP_MIGRATE_DISABLED)) || defined NVOCMP_RAM_OPTIMIZATION +static void NVOCMP_copyItem(uint8_t srcPg, uint8_t dstPg, uint16_t sOfs, uint16_t dOfs, uint16_t len); +#endif + +//***************************************************************************** +// Load Pointer Functions (These are declared in nvoctp.h) +//***************************************************************************** + +/** + * @fn NVOCMP_loadApiPtrs + * + * @brief Global function to return function pointers for NV driver API that + * are supported by this module, NULL for functions not supported. + * + * @param pfn - pointer to caller's structure of NV function pointers + * + * @return none + */ +void NVOCMP_loadApiPtrs(NVINTF_nvFuncts_t * pfn) +{ + // Load caller's structure with pointers to the NV API functions + pfn->initNV = &NVOCMP_initNvApi; + pfn->compactNV = &NVOCMP_compactNvApi; + pfn->createItem = &NVOCMP_createItemApi; + pfn->updateItem = &NVOCMP_updateItemApi; + pfn->deleteItem = &NVOCMP_deleteItemApi; + pfn->readItem = &NVOCMP_readItemApi; + pfn->readContItem = &NVOCMP_readContItemApi; + pfn->writeItem = &NVOCMP_writeItemApi; + pfn->getItemLen = &NVOCMP_getItemLenApi; + pfn->lockNV = NULL; + pfn->unlockNV = NULL; + pfn->doNext = NULL; + pfn->expectComp = &NVOCMP_expectCompApi; + pfn->eraseNV = &NVOCMP_eraseNvApi; + pfn->getFreeNV = &NVOCMP_getFreeNvApi; +#ifdef ENABLE_SANITY_CHECK + pfn->sanityCheck = &NVOCMP_sanityCheckApi; +#endif +} + +/** + * @fn NVOCMP_loadApiPtrsMin + * + * @brief Global function to return function pointers for NV driver API that + * are supported by this module, NULL for functions not supported. + * This function loads the minimum necessary API functions. + * This should allow smaller code size. + * + * @param pfn - pointer to caller's structure of NV function pointers + * + * @return none + */ +void NVOCMP_loadApiPtrsMin(NVINTF_nvFuncts_t * pfn) +{ + // Load caller's structure with pointers to the NV API functions + pfn->initNV = &NVOCMP_initNvApi; + pfn->compactNV = &NVOCMP_compactNvApi; + pfn->createItem = NULL; + pfn->updateItem = NULL; + pfn->deleteItem = NULL; + pfn->readItem = &NVOCMP_readItemApi; + pfn->readContItem = NULL; + pfn->writeItem = &NVOCMP_writeItemApi; + pfn->getItemLen = NULL; + pfn->lockNV = NULL; + pfn->unlockNV = NULL; + pfn->doNext = NULL; + pfn->expectComp = &NVOCMP_expectCompApi; + pfn->eraseNV = &NVOCMP_eraseNvApi; + pfn->getFreeNV = &NVOCMP_getFreeNvApi; +#ifdef ENABLE_SANITY_CHECK + pfn->sanityCheck = &NVOCMP_sanityCheckApi; +#endif +} + +/** + * @fn NVOCMP_loadApiPtrsExt + * + * @brief Global function to return function pointers for NV driver API that + * are supported by this module, NULL for functions not supported. + * This function also loads the 'extended' API function pointers. + * + * @param pfn - pointer to caller's structure of NV function pointers + * + * @return none + */ +void NVOCMP_loadApiPtrsExt(NVINTF_nvFuncts_t * pfn) +{ + // Load caller's structure with pointers to the NV API functions + pfn->initNV = &NVOCMP_initNvApi; + pfn->compactNV = &NVOCMP_compactNvApi; + pfn->createItem = &NVOCMP_createItemApi; + pfn->updateItem = &NVOCMP_updateItemApi; + pfn->deleteItem = &NVOCMP_deleteItemApi; + pfn->readItem = &NVOCMP_readItemApi; + pfn->readContItem = &NVOCMP_readContItemApi; + pfn->writeItem = &NVOCMP_writeItemApi; + pfn->getItemLen = &NVOCMP_getItemLenApi; + pfn->lockNV = &NVOCMP_lockNvApi; + pfn->unlockNV = &NVOCMP_unlockNvApi; + pfn->doNext = &NVOCMP_doNextApi; + pfn->expectComp = &NVOCMP_expectCompApi; + pfn->eraseNV = &NVOCMP_eraseNvApi; + pfn->getFreeNV = &NVOCMP_getFreeNvApi; +#ifdef ENABLE_SANITY_CHECK + pfn->sanityCheck = &NVOCMP_sanityCheckApi; +#endif +} + +/** + * @fn NVOCMP_setCheckVoltage + * + * @brief Global function to allow user to provide a voltage check function + * for the driver to use. If a pointer is provided, the driver will + * call the provided function before flash erases and writes. The + * provided function should return true when the battery voltage is + * sufficient and vice versa. The user can withdraw their function + * by passing a NULL pointer to this function. + * + * @param funcPtr - pointer to a function which returns a bool. + * + * @return none + */ +extern void NVOCMP_setCheckVoltage(void * funcPtr) +{ +#ifndef NV_LINUX + NVOCMP_voltCheckFptr = (bool (*)()) funcPtr; +#else + // Do nothing + (void) NVOCMP_voltCheckFptr; +#endif +} + +#ifdef NVOCMP_MIN_VDD_FLASH_MV +/** + * @fn NVOCMP_setLowVoltageCb + * + * @brief Global function to allow user to provide a low voltage callback function + * for the driver to use. If a pointer is provided, the driver will + * call the provided function when low voltage detected. + * + * @param funcPtr - pointer to a function. + * + * @return none + */ +static lowVoltCbFptr NVOCMP_lowVoltCbFptr = NULL; +extern void NVOCMP_setLowVoltageCb(lowVoltCbFptr funcPtr) +{ +#ifndef NV_LINUX + NVOCMP_lowVoltCbFptr = (lowVoltCbFptr) funcPtr; +#else + // Do nothing + (void) NVOCMP_lowVoltCbFptr; +#endif +} + +/******************************************************************************* + * @fn NVOCMP_checkVoltage() + * + * @brief Checks the caller supplied voltage threshold against the value read + * from the CC26xx BATMON register. + * + * @param none + * + * @return false if device voltage less than limit, otherwise true + ******************************************************************************* + */ +static bool NVOCMP_checkVoltage(void) +{ + uint32_t voltage = AONBatMonBatteryVoltageGet(); + voltage = (voltage * 1000) >> AON_BATMON_BAT_FRAC_W; + if (voltage < NVOCMP_MIN_VDD_FLASH_MV) + { + // Measured device voltage is below threshold + if (NVOCMP_lowVoltCbFptr) + { + NVOCMP_lowVoltCbFptr(voltage); + } + return (false); + } + + return (true); +} +#endif + +#ifdef NVDEBUG +void NVOCMP_corruptData(uint8_t pg, uint16_t off, uint16_t len, uint8_t buf) +{ + NVS_write(NVOCMP_nvsHandle, NVOCMP_FLASHOFFSET(pg, off), (uint8_t *) &buf, len, NVS_WRITE_POST_VERIFY); +} +#endif + +/****************************************************************************** + * @fn NVOCMP_initNvApi + * + * @brief API function to initialize the specified NV Flash pages + * + * @param param - pointer to caller's structure of NV init parameters + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_initNvApi(void * param) +{ + NVOCMP_ALERT(false, "NVOCMP Init. Called!") + NVOCMP_failW = NVOCMP_failF; + + if (NVOCMP_failF == NVINTF_NOTREADY) + { +#ifdef NVOCMP_POSIX_MUTEX + pthread_mutexattr_t attr; +#elif defined(NVOCMP_POSIX_SEM) +#else + GateMutexPri_Params gateParams; +#endif + + // Only one init per device reset + NVOCMP_failF = NVINTF_SUCCESS; + NVOCMP_failW = NVINTF_SUCCESS; + + // Create a priority gate mutex for the NV driver +#ifdef NVOCMP_POSIX_MUTEX + if (pthread_mutexattr_init(&attr) != 0) + { + NVOCMP_failF = NVINTF_FAILURE; + return (NVOCMP_failF); + } + +#ifndef NV_LINUX + attr.type = PTHREAD_MUTEX_RECURSIVE; +#else + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); +#endif + if (pthread_mutex_init(&NVOCMP_gPosixMutex, &attr) != 0) + { + NVOCMP_failF = NVINTF_FAILURE; + return (NVOCMP_failF); + } +#elif defined(NVOCMP_POSIX_SEM) + sem_init(&NVOCMP_gPosixSem, 0 /* ignored */, 1); +#else + GateMutexPri_Params_init(&gateParams); + NVOCMP_gMutexPri = GateMutexPri_create(&gateParams, NULL); +#endif + + memset(&NVOCMP_nvHandle, 0, sizeof(NVOCMP_nvHandle_t)); + memset(&NVOCMP_nvHandle.compactInfo, 0xFF, sizeof(NVOCMP_compactInfo_t)); + +#ifndef NV_LINUX +#ifdef NVOCMP_MIN_VDD_FLASH_MV + NVOCMP_setCheckVoltage((void *) &NVOCMP_checkVoltage); +#endif + // Initialize NVS objects + NVS_init(); + + // Use default NVS_Params to open this flash region + NVOCMP_nvsHandle = NVS_open(NVOCMP_NVS_INDEX, param); + + // Get NV hardware attributes + NVS_getAttrs(NVOCMP_nvsHandle, &NVOCMP_nvsAttrs); +#else + NV_LINUX_init(); + + NVOCMP_nvsHandle = NVS_HANDLE; + NVOCMP_nvsAttrs.sectorSize = FLASH_PAGE_SIZE; + NVOCMP_nvsAttrs.regionSize = FLASH_PAGE_SIZE * NVOCMP_NVPAGES; +#endif + + NVOCMP_nvHandle.nvSize = NVOCMP_nvsAttrs.regionSize / NVOCMP_nvsAttrs.sectorSize; + NVOCMP_nvHandle.nvSize = NVOCMP_nvHandle.nvSize > NVOCMP_NVPAGES ? NVOCMP_NVPAGES : NVOCMP_nvHandle.nvSize; + NVOCMP_size = NVOCMP_nvHandle.nvSize; + + // Confirm NV region has expected characteristics + if (FLASH_PAGE_SIZE != NVOCMP_nvsAttrs.sectorSize || (NVOCMP_NVSIZE * FLASH_PAGE_SIZE > NVOCMP_nvsAttrs.regionSize)) + { + NVOCMP_failF = NVINTF_FAILURE; + NVOCMP_EXCEPTION(pg, NVINTF_FAILURE) + return (NVOCMP_failF); + } + + // Confirm that the NVS region opened properly + if (NVOCMP_nvsHandle == NULL) + { + NVOCMP_failF = NVINTF_FAILURE; + NVOCMP_ASSERT(false, "NVS HANDLE IS NULL") + NVOCMP_EXCEPTION(pg, NVINTF_NOTREADY); + return (NVOCMP_failF); + } + + // Initialize force compaction to false + NVOCMP_nvHandle.forceCompact = 0; + + // Look for active page and clean up the other if necessary + NVOCMP_nvHandle.actPage = NVOCMP_NULLPAGE; + NVOCMP_nvHandle.actOffset = FLASH_PAGE_SIZE; + + NVOCMP_initNv(&NVOCMP_nvHandle); + +#if defined(NVOCMP_STATS) + { + uint8_t err; + NVOCMP_diag_t diags; + + // Look for a copy of diagnostic info + err = NVOCMP_readItemApi(diagId, 0, sizeof(diags), &diags); + if (err == NVINTF_NOTFOUND) + { + // Assume this is the first time, + memset(&diags, 0, sizeof(diags)); + // Space available for everything else + diags.available = FLASH_PAGE_SIZE - (NVOCMP_nvHandle.actOffset + NVOCMP_ITEMHDRLEN + sizeof(diags)); + } + // Remember this reset + diags.resets += 1; + // Create/Update the diagnostic NV item + NVOCMP_writeItemApi(diagId, sizeof(diags), &diags); + } +#endif // NVOCMP_STATS + } + + return (NVOCMP_failW); +} + +/****************************************************************************** + * @fn NVOCMP_eraseNvApi + * + * @brief API function to erase whole NV pages + * + * @param none + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_eraseNvApi(void) +{ + uint8_t pg; + uint8_t err = NVINTF_SUCCESS; + + // Check voltage if possible + NVOCMP_FLASHACCESS(err) + if (err) + { + return (err); + } + + NVOCMP_LOCK(); + + // Erase All pages before start + for (pg = 0; pg < NVOCMP_NVSIZE; pg++) + { + NVOCMP_failW |= NVOCMP_erase(&NVOCMP_nvHandle, pg); + } + + err = NVOCMP_failW; + + // initial state, set head page, act page and tail page + NVOCMP_nvHandle.headPage = 0; + NVOCMP_nvHandle.tailPage = NVOCMP_NVSIZE - 1; + NVOCMP_nvHandle.actPage = 0; + NVOCMP_nvHandle.actOffset = NVOCMP_nvHandle.pageInfo[NVOCMP_nvHandle.actPage].offset; + NVOCMP_changePageState(&NVOCMP_nvHandle, NVOCMP_nvHandle.headPage, NVOCMP_PGRDY); + NVOCMP_changePageState(&NVOCMP_nvHandle, NVOCMP_nvHandle.tailPage, NVOCMP_PGXDST); + +#ifdef NV_LINUX + if (err == NVINTF_SUCCESS) + { + NV_LINUX_save(); + } +#endif + + NVOCMP_UNLOCK(err); +} + +/****************************************************************************** + * @fn NVOCMP_getFreeNvApi + * + * @brief API function to get free space in whole NV pages + * + * @param none + * + * @return bytes of free space + */ +static uint32_t NVOCMP_getFreeNvApi(void) +{ + uint8_t pg = NVOCMP_nvHandle.actPage; + NVOCMP_pageHdr_t pageHdr; + uint32_t freespace = 0; +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) + uint16_t nvSearched = 0; + for (pg = NVOCMP_nvHandle.actPage; nvSearched < NVOCMP_NVSIZE; pg = NVOCMP_INCPAGE(pg)) + { + nvSearched++; + if (pg == NVOCMP_nvHandle.tailPage) + { + continue; + } +#endif + NVOCMP_read(pg, NVOCMP_PGHDROFS, (uint8_t *) &pageHdr, NVOCMP_PGHDRLEN); + if ((pageHdr.state == NVOCMP_PGNACT) || (pageHdr.state == NVOCMP_PGRDY) || (pageHdr.state == NVOCMP_PGACT)) + { + freespace += (FLASH_PAGE_SIZE - NVOCMP_nvHandle.pageInfo[pg].offset); + } +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) + } +#endif + return (freespace); +} + +/****************************************************************************** + * @fn NVOCMP_compactNvApi + * + * @brief API function to force NV active page compaction + * + * @param minAvail - threshold size of available bytes on Flash page to do + * compaction: 0 = always, >0 = minimum remaining bytes + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_compactNvApi(uint16_t minAvail) +{ + uint8_t err = NVINTF_SUCCESS; + + // Check voltage if possible + NVOCMP_FLASHACCESS(err) + if (err) + { + return (err); + } + + // Prevent RTOS thread contention + NVOCMP_LOCK(); + NVOCMP_ALERT(false, "API Compaction Request.") + err = NVOCMP_failF; + // Check for a fatal error + if (err == NVINTF_SUCCESS) + { + int16_t left; + + // Number of bytes left on active page + left = FLASH_PAGE_SIZE - NVOCMP_nvHandle.actOffset; + + // Time to do a compaction? + if ((left < minAvail) || (minAvail == 0)) + { + // Transfer all items to non-ACTIVE page + (void) NVOCMP_compactPage(&NVOCMP_nvHandle, 0); + // 'failW' indicates compaction status + err = NVOCMP_failW; + } + else + { + // Indicate "bad" minAvail value + err = NVINTF_BADPARAM; + } + } + +#ifdef NV_LINUX + if (err == NVINTF_SUCCESS) + { + NV_LINUX_save(); + } +#endif + + NVOCMP_UNLOCK(err); +} + +//***************************************************************************** +// API Functions - NV Data Items +//***************************************************************************** + +/****************************************************************************** + * @fn NVOCMP_createItemApi + * + * @brief API function to create a new NV item in Flash memory. This function + * will return an error if the specified item already exists. + * + * @param id - NV item type identifier + * @param len - length of NV data + * @param pBuf - pointer to caller's data buffer (NULL is illegal) + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_createItemApi(NVINTF_itemID_t id, uint32_t len, void * pBuf) +{ + uint8_t err; + NVOCMP_itemHdr_t iHdr; + + // Parameter Sanity Check + if (pBuf == NULL || len == 0) + { + return (NVINTF_BADPARAM); + } + + err = NVOCMP_checkItem(&id, len, &iHdr, NVOCMP_FINDSTRICT); + if (err) + { + return (err); + } + + // Check voltage if possible + NVOCMP_FLASHACCESS(err) + if (err) + { + return (err); + } + + // Prevent RTOS thread contention + NVOCMP_LOCK(); + + err = NVOCMP_findItem(&NVOCMP_nvHandle, NVOCMP_nvHandle.actPage, NVOCMP_nvHandle.actOffset, &iHdr, NVOCMP_FINDSTRICT, NULL); + + if (err == NVINTF_SUCCESS) + { + err = NVINTF_EXIST; + } + else if (err == NVINTF_NOTFOUND) + { + // Create the new item + err = NVOCMP_addItem(&NVOCMP_nvHandle, &iHdr, pBuf, NVOCMP_CREATE); + if (err != NVINTF_SUCCESS) + { + NVOCMP_ALERT(false, "createItem failed.") + err = NVINTF_FAILURE; + } + } + else + { + NVOCMP_ALERT(false, "createItem failed.") + err = NVINTF_FAILURE; + } + +#ifdef NV_LINUX + if (err == NVINTF_SUCCESS) + { + NV_LINUX_save(); + } +#endif + + NVOCMP_UNLOCK(err); +} + +/****************************************************************************** + * @fn NVOCMP_updateItemApi + * + * @brief API function to update an existing NV item in Flash memory. This function + * will return an error if the specified item does not exist. + * + * @param id - NV item type identifier + * @param len - length of NV data + * @param pBuf - pointer to caller's data buffer (NULL is illegal) + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_updateItemApi(NVINTF_itemID_t id, uint32_t len, void * pBuf) +{ + uint8_t err; + NVOCMP_itemHdr_t iHdr; + + // Parameter Sanity Check + if (pBuf == NULL || len == 0) + { + return (NVINTF_BADPARAM); + } + + err = NVOCMP_checkItem(&id, len, &iHdr, NVOCMP_FINDSTRICT); + if (err) + { + return (err); + } + + // Check voltage if possible + NVOCMP_FLASHACCESS(err) + if (err) + { + return (err); + } + + // Prevent RTOS thread contention + NVOCMP_LOCK(); + + err = NVOCMP_findItem(&NVOCMP_nvHandle, NVOCMP_nvHandle.actPage, NVOCMP_nvHandle.actOffset, &iHdr, NVOCMP_FINDSTRICT, NULL); + + if (err == NVINTF_SUCCESS) + { + // Create the new item + err = NVOCMP_addItem(&NVOCMP_nvHandle, &iHdr, pBuf, NVOCMP_UPDATE); + if ((err == NVINTF_SUCCESS) && (iHdr.hofs > 0)) + { + // Mark old item as inactive + NVOCMP_setItemInactive(&NVOCMP_nvHandle, iHdr.hpage, iHdr.hofs); + + err = NVOCMP_failW; + } + } + else if (err == NVINTF_NOTFOUND) + { + err = NVINTF_NOTFOUND; + } + else + { + NVOCMP_ALERT(false, "updateItem failed.") + err = NVINTF_FAILURE; + } + +#ifdef NV_LINUX + if (err == NVINTF_SUCCESS) + { + NV_LINUX_save(); + } +#endif + + NVOCMP_UNLOCK(err); +} + +/****************************************************************************** + * @fn NVOCMP_deleteItemApi + * + * @brief API function to delete an existing NV item from Flash memory. Note, + * it is inefficient to use this function to delete a range of items. + * The doNext call is recommended for that use case. + * + * @param id - NV item type identifier + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_deleteItemApi(NVINTF_itemID_t id) +{ + uint8_t err; + NVOCMP_itemHdr_t iHdr; + +#if defined(NVOCMP_STATS) + if (!memcmp(&id, &diagId, sizeof(NVINTF_itemID_t))) + { + // Protect NV driver item(s) + return (NVINTF_BADSYSID); + } +#endif // NVOCMP_STATS + + err = NVOCMP_checkItem(&id, 0, &iHdr, NVOCMP_FINDSTRICT); + if (err) + { + return (err); + } + + // Check voltage if possible + NVOCMP_FLASHACCESS(err) + if (err) + { + return (err); + } + + // Prevent RTOS thread contention + NVOCMP_LOCK(); + + err = NVOCMP_findItem(&NVOCMP_nvHandle, NVOCMP_nvHandle.actPage, NVOCMP_nvHandle.actOffset, &iHdr, NVOCMP_FINDSTRICT, NULL); + + if (!err) + { + // Mark this item as inactive + NVOCMP_setItemInactive(&NVOCMP_nvHandle, iHdr.hpage, iHdr.hofs); + + // Verify that item has been removed + err = (NVOCMP_findItem(&NVOCMP_nvHandle, NVOCMP_nvHandle.actPage, NVOCMP_nvHandle.actOffset, &iHdr, NVOCMP_FINDSTRICT, + NULL) == NVINTF_NOTFOUND) + ? NVOCMP_failW + : NVINTF_FAILURE; + + // If item did get deleted, report 'failW' status + NVOCMP_ALERT(err == NVOCMP_failW, "Item delete failed.") + } + +#ifdef NV_LINUX + if (err == NVINTF_SUCCESS) + { + NV_LINUX_save(); + } +#endif + + NVOCMP_UNLOCK(err); +} + +/****************************************************************************** + * @fn NVOCMP_getItemLenApi + * + * @brief API function to return the length of an NV data item + * + * @param id - NV item type identifier + * + * @return NV item length or 0 if item not found + */ +static uint32_t NVOCMP_getItemLenApi(NVINTF_itemID_t id) +{ + uint8_t err; + uint32_t len = 0; + NVOCMP_itemHdr_t iHdr; + + err = NVOCMP_checkItem(&id, 0, &iHdr, NVOCMP_FINDSTRICT); + if (err) + { + return (len); + } + + // Prevent RTOS thread contention + NVOCMP_LOCK(); + + // If there was any error, report zero length + len = (NVOCMP_findItem(&NVOCMP_nvHandle, NVOCMP_nvHandle.actPage, NVOCMP_nvHandle.actOffset, &iHdr, NVOCMP_FINDSTRICT, NULL) != + NVINTF_SUCCESS) + ? 0 + : iHdr.len; + + NVOCMP_UNLOCK(len); +} + +/****************************************************************************** + * @fn NVOCMP_readContItemApi + * + * @brief API function to read data from an NV item by comparing content + * + * @param id - NV item type identifier + * @param ofs - offset into NV data + * @param rlen - length of NV data to return (0 is illegal) + * @param rBuf - pointer to caller's read data buffer (NULL is illegal) + * @param clen - length of NV data to return (0 is illegal) + * @param coff - offset of content in data + * @param cBuf - pointer to caller's read data buffer (NULL is illegal) + * @param pSubId - pointer to store sub Id (NULL is illegal) + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_readContItemApi(NVINTF_itemID_t id, uint16_t ofs, uint16_t rlen, void * rBuf, uint16_t clen, uint16_t coff, + void * cBuf, uint16_t * pSubId) +{ + uint8_t err; + NVOCMP_itemHdr_t iHdr; + NVOCMP_itemInfo_t itemInfo; + + *pSubId = NVOCMP_INVALIDSUBID; + // Parameter Sanity Check + if (rBuf == NULL || rlen == 0 || cBuf == NULL || clen == 0 || coff > FLASH_PAGE_SIZE) + { + return (NVINTF_BADPARAM); + } + + err = NVOCMP_checkItem(&id, rlen, &iHdr, NVOCMP_FINDSTRICT); + if (err) + { + return (err); + } + + // Prevent RTOS thread contention + NVOCMP_LOCK(); + + itemInfo.cBuf = cBuf; + itemInfo.clength = clen; + itemInfo.coff = coff; + itemInfo.rBuf = rBuf; + itemInfo.rlength = rlen; + err = NVOCMP_findItem(&NVOCMP_nvHandle, NVOCMP_nvHandle.actPage, NVOCMP_nvHandle.actOffset, &iHdr, + NVOCMP_FINDITMID | NVOCMP_FINDCONTENT, &itemInfo); + + if (!err) + { + *pSubId = iHdr.subid; + } + + NVOCMP_UNLOCK(err); +} + +/****************************************************************************** + * @fn NVOCMP_readItemApi + * + * @brief API function to read data from an NV item + * + * @param id - NV item type identifier + * @param ofs - offset into NV data + * @param len - length of NV data to return (0 is illegal) + * @param pBuf - pointer to caller's read data buffer (NULL is illegal) + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_readItemApi(NVINTF_itemID_t id, uint16_t ofs, uint16_t len, void * pBuf) +{ + uint8_t err; + NVOCMP_itemHdr_t iHdr; + + // Parameter Sanity Check + if (pBuf == NULL || len == 0) + { + return (NVINTF_BADPARAM); + } + + err = NVOCMP_checkItem(&id, len, &iHdr, NVOCMP_FINDSTRICT); + if (err) + { + return (err); + } + + // Prevent RTOS thread contention + NVOCMP_LOCK(); + + err = NVOCMP_findItem(&NVOCMP_nvHandle, NVOCMP_nvHandle.actPage, NVOCMP_nvHandle.actOffset, &iHdr, NVOCMP_FINDSTRICT, NULL); + + // Read Item + if (!err) + { + err = NVOCMP_readItem(&iHdr, ofs, len, pBuf, false); + } + + NVOCMP_UNLOCK(err); +} + +/****************************************************************************** + * @fn NVOCMP_writeItemApi + * + * @brief API function to write data to item, creates item if needed. + * Note that when writing to an existing item, data is not + * checked for redundancy. Data passed to this function will be + * written to NV. NOTE: It is not recommended to write items with + * SYSID 0 as this is reserved for the driver. NVOCMP will not + * delete items with this SYSID. + * + * @param id - NV item type identifier + * @param len - data buffer length to write into NV block (0 is illegal) + * @param pBuf - pointer to caller's data buffer to write (NULL is illegal) + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_writeItemApi(NVINTF_itemID_t id, uint16_t len, void * pBuf) +{ + uint8_t err; + NVOCMP_itemHdr_t iHdr; + + // Parameter Sanity Check + if (pBuf == NULL || len == 0) + { + return (NVINTF_BADPARAM); + } + + err = NVOCMP_checkItem(&id, len, &iHdr, NVOCMP_FINDSTRICT); + if (err) + { + return (err); + } + + // Check voltage if possible + NVOCMP_FLASHACCESS(err) + if (err) + { + return (err); + } + + // Prevent RTOS thread contention + NVOCMP_LOCK(); + + // Create a new item + err = NVOCMP_addItem(&NVOCMP_nvHandle, &iHdr, pBuf, NVOCMP_WRITE); + if ((err == NVINTF_SUCCESS) && (iHdr.hofs > 0)) + { + // Mark old item as inactive + NVOCMP_setItemInactive(&NVOCMP_nvHandle, iHdr.hpage, iHdr.hofs); + + err = NVOCMP_failW; + } + +#ifdef NV_LINUX + if (err == NVINTF_SUCCESS) + { + NV_LINUX_save(); + } +#endif + + NVOCMP_UNLOCK(err); +} + +//***************************************************************************** +// Extended API Functions +//***************************************************************************** + +/** + * @fn NVOCMP_lockNvApi + * + * @brief Global function to lock the NV priority gate mutex + * + * @return Key value needed to unlock the gate + */ +static int32_t NVOCMP_lockNvApi(void) +{ +#ifdef NVOCMP_POSIX_MUTEX + return (pthread_mutex_lock(&NVOCMP_gPosixMutex)); +#elif defined(NVOCMP_POSIX_SEM) + return (sem_wait(&NVOCMP_gPosixSem)); +#else + return (GateMutexPri_enter(NVOCMP_gMutexPri)); +#endif +} + +/** + * @fn NVOCMP_unlockNvApi + * + * @brief Global function to unlock the NV priority gate mutex + * + * @return none + */ +static void NVOCMP_unlockNvApi(int32_t key) +{ +#ifdef NVOCMP_POSIX_MUTEX + (void) key; + pthread_mutex_unlock(&NVOCMP_gPosixMutex); +#elif defined(NVOCMP_POSIX_SEM) + (void) key; + sem_post(&NVOCMP_gPosixSem); +#else + GateMutexPri_leave(NVOCMP_gMutexPri, key); +#endif +} + +/****************************************************************************** + * @fn NVOCMP_doNextApi + * + * @brief API function which allows operations on batches of NV items. This + * function provides a faster way of finding, reading, or deleting multiple + * NV items. However, the user must first lock access to NV with lockNV() to + * ensure consistent results. The user must take care to minimize the time NV + * is locked if NV access is shared. User must also remember to unlock NV when + * done with unlockNV(). + * + * Usage Details: + * doNext is controlled through the nvProxy item pointed to by prx + * User will set flag bit NVINTF_DOSTART and then other flags based on the + * desired operation. For example to find all items in system NVINTF_SYS_BLE, + * the user would set flag bit NVINTF_DOFIND and set prx->sysid = NVINTF_SYS_BLE. + * Then every call to doNextApi() returns with a status code and with the proxy + * item populated with the found item if there was one. NVINTF_SUCCESS is + * returned on a successful item operation, NVINTF_NOTFOUND is returned when a + * matching item is not found, and other error codes can be returned. + * Sample Code: + * + * // Use doNext to delete items of sysid + * NVINTF_nvFuncts_t nvFps; + * NVINTF_nvProxy_t nvProxy; + * NVOCMP_loadApiPtrsExt(&nvFps); + * nvFps.initNV(NULL); + * nvProxy.sysid = sysid; + * nvProxy.flag = NVINTF_DOSTART | NVINTF_DOSYSID | NVINTF_DODELETE; + * + * key = nvFps.lockNV(); + * while(!status) + * { + * status |= nvFps.doNext(&nvProxy); + * } + * nvFps.unlockNV(key); + * + * Notes: + * -User changes to the proxy struct will have no effect until a new search is + * started by setting NVINTF_DOSTART + * -On read operations, the user will supply a buffer and length into the proxy + * -Items with system id NVINTF_SYSID_NVDRVR cannot be deleted with this API, + * deleteItemApi must be used one an individual item basis + * + * @param prx - pointer to nvProxy item which contains user inputs + * + * @return NVINTF_SUCCESS or specific failure code + */ + +static uint8_t NVOCMP_doNextApi(NVINTF_nvProxy_t * prx) +{ + static enum { doFind, doRead, doDelete } op = doFind; + NVOCMP_itemHdr_t hdr; + static uint8_t search; + static uint8_t sPage; + static int16_t fOfs = FLASH_PAGE_SIZE; + static uint16_t bufLen = 0; + uint8_t status = NVINTF_SUCCESS; + int16_t iOfs = NVOCMP_nvHandle.actOffset; + static int16_t initialFindiofs = -1; + static uint8_t initialsPage = 0xFF; + + // Sanitize inputs + if (NULL == prx) + { + return (NVINTF_BADPARAM); + } + else if (0 == prx->flag) + { + return (NVINTF_BADPARAM); + } + + // Locks NV + NVOCMP_LOCK(); + + // New search if start flag set + if (prx->flag & NVINTF_DOSTART) + { + // Remove start flag + prx->flag &= ~NVINTF_DOSTART; + // Start at latest item + sPage = NVOCMP_nvHandle.actPage; + fOfs = NVOCMP_nvHandle.actOffset; + + initialFindiofs = -1; + initialsPage = 0xFF; + + // Read in buffer len + bufLen = prx->len; + // Decode flag + if (prx->flag & NVINTF_DOSYSID) + { + search = NVOCMP_FINDSYSID; + } + else if (prx->flag & NVINTF_DOITMID) + { + search = NVOCMP_FINDITMID; + } + else if (prx->flag & NVINTF_DOANYID) + { + search = NVOCMP_FINDANY; + } + if (prx->flag & NVINTF_DOFIND) + { + op = doFind; + } + else if (prx->flag & NVINTF_DOREAD) + { + op = doRead; + } + else if (prx->flag & NVINTF_DODELETE) + { + op = doDelete; + } + } + + hdr.sysid = prx->sysid; + hdr.itemid = prx->itemid; + hdr.subid = prx->subid; + // Look for item + if (!NVOCMP_findItem(&NVOCMP_nvHandle, sPage, fOfs, &hdr, search, NULL)) + { + iOfs = hdr.hofs; + // store its attributes + prx->sysid = hdr.sysid; + prx->itemid = hdr.itemid; + prx->subid = hdr.subid; + prx->len = hdr.len; + + if (prx->flag & NVINTF_DONOWRAP) + { + if ((initialFindiofs == hdr.hofs) && (initialsPage == hdr.hpage)) + { + status = NVINTF_NOTFOUND; + } + + if ((initialFindiofs == -1) && (initialsPage == 0xFF)) + { + initialFindiofs = hdr.hofs; + initialsPage = hdr.hpage; + } + } + + // start from this item on next findItem() + fOfs = iOfs - hdr.len; + sPage = hdr.hpage; + + if (status == NVINTF_SUCCESS) + { + // Do operation based on flag + switch (op) + { + case doFind: + // nothing, we already stored its info + break; + case doRead: + // read item into user supplied buffer + if (prx->buffer != NULL && hdr.len <= bufLen) + { + status = NVOCMP_readItem(&hdr, 0, hdr.len, prx->buffer, false); + } + break; + case doDelete: + if (prx->sysid != NVINTF_SYSID_NVDRVR) + { + NVOCMP_setItemInactive(&NVOCMP_nvHandle, hdr.hpage, iOfs); + } + break; + default: + NVOCMP_ALERT(false, "doNext flag is invalid.") + status = NVINTF_BADPARAM; + } + } + } + else + { + // No more items match, done. + status = NVINTF_NOTFOUND; + } + + // Unlocks NV + NVOCMP_UNLOCK(status); +} +/****************************************************************************** + * @fn NVOCMP_expectCompApi + * + * @brief API function to check if compaction will happen if a data with size = len is written + * + * @param len - data buffer length to write into NV block + * + * @return true or false + */ +static bool NVOCMP_expectCompApi(uint16_t len) +{ + uint8_t dstPg; + uint16_t iLen; + bool compact = false; + + if (len) + { + iLen = NVOCMP_ITEMHDRLEN + len; + dstPg = NVOCMP_getDstPage(&NVOCMP_nvHandle, iLen); + + if (dstPg == NVOCMP_NULLPAGE) + { + compact = true; + } + } + return (compact); +} + +//***************************************************************************** +// Local NV Driver Utility Functions +//***************************************************************************** + +#ifdef NVOCMP_GPRAM +/****************************************************************************** + * @fn NVOCMP_disableCache + * + * @brief Local function to disable cache + * + * @param vm - pointer to mode storage + * + * @return none + */ +static void NVOCMP_disableCache(uint32_t * vm) +{ + // Save current cache mode + *vm = VIMSModeGet(VIMS_BASE) & VIMS_STAT_MODE_M; + // Disable the cache + VIMSModeSet(VIMS_BASE, VIMS_MODE_DISABLED); + // Wait until it is + while (VIMSModeGet(VIMS_BASE) != VIMS_MODE_DISABLED) + ; +} + +/****************************************************************************** + * @fn NVOCMP_restoreCache + * + * @brief Local function to disable cache + * + * @param vm - mode + * + * @return none + */ +static void NVOCMP_restoreCache(uint32_t vm) +{ + // Restore cache to previous state + VIMSModeSet(VIMS_BASE, vm); +} +#endif + +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) +/****************************************************************************** + * @fn NVOCMP_findPage + * + * @brief Local function to find page with specified state + * + * @param state - page state to find + * + * @return page number or NVOCMP_NULLPAGE + */ +static uint8_t NVOCMP_findPage(NVOCMP_pageState_t state) +{ + uint8_t pg; + NVOCMP_pageHdr_t pageHdr; + + for (pg = 0; pg < NVOCMP_NVSIZE; pg++) + { + // Get page header + NVOCMP_read(pg, NVOCMP_PGHDROFS, (uint8_t *) &pageHdr, NVOCMP_PGHDRLEN); + if (pageHdr.state == state) + { + return (pg); + } + } + return (NVOCMP_NULLPAGE); +} +#endif + +#if (NVOCMP_NVPAGES > NVOCMP_NVONEP) +#if !defined(NVOCMP_MIGRATE_DISABLED) +/****************************************************************************** + * @fn NVOCMP_migratePage + * + * @brief Local function to find page with specified state + * + * @param pNvHandle - pointer to NV handle + * @param page - page to convert + * + * @return none + */ +static void NVOCMP_migratePage(NVOCMP_nvHandle_t * pNvHandle, uint8_t page) +{ + uint8_t dstPg; + uint8_t tmp; + uint16_t offset1; + uint16_t offset2; + NVOCMP_itemHdr_t iHdr; + + offset1 = pNvHandle->pageInfo[page].offset; + offset2 = NVOCTP_PGDATAOFS; + if (offset1 - NVOCTP_PGDATAOFS > FLASH_PAGE_SIZE - NVOCMP_PGDATAOFS) + { + offset2 = offset1; + while (offset2 - NVOCTP_PGDATAOFS > FLASH_PAGE_SIZE - NVOCMP_PGDATAOFS) + { + NVOCMP_findItem(pNvHandle, page, offset2, &iHdr, NVOCMP_FINDANY, NULL); + offset2 = iHdr.hofs - iHdr.len; + } + } + if ((pNvHandle->nvSize <= NVOCMP_NVTWOP) && (offset2 != NVOCTP_PGDATAOFS)) + { + offset1 = offset2; + offset2 = NVOCTP_PGDATAOFS; + } + + dstPg = page; + // copy from offset2 to top + if (offset2 - NVOCTP_PGDATAOFS > 0) + { + dstPg = NVOCMP_INCPAGE(dstPg); + NVOCMP_copyItem(page, dstPg, NVOCTP_PGDATAOFS, NVOCMP_PGDATAOFS, offset2 - NVOCTP_PGDATAOFS); + NVOCMP_changePageState(pNvHandle, dstPg, NVOCMP_PGFULL); + pNvHandle->pageInfo[dstPg].allActive = NVOCMP_SOMEINACTIVE; + pNvHandle->pageInfo[dstPg].offset = NVOCMP_PGDATAOFS + offset2 - NVOCTP_PGDATAOFS; + pNvHandle->actPage = dstPg; + pNvHandle->actOffset = pNvHandle->pageInfo[dstPg].offset; + tmp = NVOCMP_readByte(dstPg, NVOCMP_PGHDRVER); + tmp &= ~NVOCMP_ALLACTIVE; + NVOCMP_writeByte(dstPg, NVOCMP_PGHDRVER, tmp); + } + // copy from offset 1 to offset2 + if (offset1 - offset2 > 0) + { + dstPg = NVOCMP_INCPAGE(dstPg); + NVOCMP_copyItem(page, dstPg, offset2, NVOCMP_PGDATAOFS, offset1 - offset2); + NVOCMP_changePageState(pNvHandle, dstPg, NVOCMP_PGFULL); + pNvHandle->pageInfo[dstPg].allActive = NVOCMP_SOMEINACTIVE; + pNvHandle->pageInfo[dstPg].offset = NVOCMP_PGDATAOFS + offset1 - offset2; + pNvHandle->actPage = dstPg; + pNvHandle->actOffset = pNvHandle->pageInfo[dstPg].offset; + tmp = NVOCMP_readByte(dstPg, NVOCMP_PGHDRVER); + tmp &= ~NVOCMP_ALLACTIVE; + NVOCMP_writeByte(dstPg, NVOCMP_PGHDRVER, tmp); + } + + NVOCMP_failW |= NVOCMP_erase(pNvHandle, page); + pNvHandle->tailPage = page; + pNvHandle->headPage = NVOCMP_INCPAGE(page); + NVOCMP_changePageState(pNvHandle, page, NVOCMP_PGXDST); +} +#endif +#endif + +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) +/****************************************************************************** + * @fn NVOCMP_scanPage + * + * @brief Local function to scan page to get page information + * + * @param pNvHandle - pointer to NV handle + * @param pg - page to scan + * @param pPageInfo - page info pointer + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_scanPage(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, NVOCMP_pageInfo_t * pPageInfo) +{ + uint32_t pageHdr; + NVOCMP_compactHdr_t thisHdr; + NVOCMP_compactHdr_t startHdr; + NVOCMP_compactHdr_t endHdr; + NVOCMP_pageHdr_t * pHdr = (NVOCMP_pageHdr_t *) &pageHdr; + + // Get page header + NVOCMP_read(pg, NVOCMP_PGHDROFS, (uint8_t *) pHdr, NVOCMP_PGHDRLEN); +#if ((NVOCMP_NVPAGES != NVOCMP_NVONEP) && !defined(NVOCMP_MIGRATE_DISABLED)) + uint8_t version = (pHdr->version << 2) | (pHdr->allActive); + if ((pHdr->signature == NVOCTP_SIGNATURE) && (version == NVOCTP_VERSION)) + { + pPageInfo->state = pHdr->state; + pPageInfo->cycle = pHdr->cycle; + pPageInfo->allActive = NVOCMP_SOMEINACTIVE; + pPageInfo->mode = NVOCMP_PGNORMAL; + pPageInfo->offset = NVOCMP_findOffset(pg, FLASH_PAGE_SIZE); + return (NVINTF_SUCCESS); + } +#endif + + NVOCMP_getCompactHdr(pg, THISPAGEHDR, &thisHdr); + NVOCMP_getCompactHdr(pg, XSRCSTARTHDR, &startHdr); + NVOCMP_getCompactHdr(pg, XSRCENDHDR, &endHdr); + uint8_t corruptFlag = ((pHdr->state != NVOCMP_PGNACT) && (pHdr->state != NVOCMP_PGXDST) && (pHdr->state != NVOCMP_PGRDY) && + (pHdr->state != NVOCMP_PGACT) && (pHdr->state != NVOCMP_PGFULL) && (pHdr->state != NVOCMP_PGXSRC)); + + if (corruptFlag || (pHdr->version != NVOCMP_VERSION) || (pHdr->signature != NVOCMP_SIGNATURE)) + { + // NV page and NV driver versions are different + NVOCMP_ALERT(false, "Corrupted or Version/Signature mismatch.") + NVOCMP_EXCEPTION(pg, NVINTF_BADVERSION); + NVOCMP_failW = NVOCMP_erase(pNvHandle, pg); + if (NVOCMP_failW == NVINTF_SUCCESS) + { + // Get page header + NVOCMP_read(pg, NVOCMP_PGHDROFS, (uint8_t *) pHdr, NVOCMP_PGHDRLEN); + NVOCMP_getCompactHdr(pg, THISPAGEHDR, &thisHdr); + NVOCMP_getCompactHdr(pg, XSRCSTARTHDR, &startHdr); + NVOCMP_getCompactHdr(pg, XSRCENDHDR, &endHdr); + } + else if (NVOCMP_failW == NVINTF_LOWPOWER) + { + return (NVINTF_LOWPOWER); + } + else + { + return (NVINTF_FAILURE); + } + } + + pPageInfo->state = pHdr->state; + pPageInfo->cycle = pHdr->cycle; + pPageInfo->allActive = pHdr->allActive; + pPageInfo->mode = thisHdr.page; + if ((pPageInfo->state == NVOCMP_PGNACT) || (pPageInfo->state == NVOCMP_PGXDST)) + { + pPageInfo->offset = NVOCMP_PGDATAOFS; + } + else if (thisHdr.pageOffset != NVOCMP_NULLOFFSET) + { + pPageInfo->offset = thisHdr.pageOffset; + } + else + { + pPageInfo->offset = NVOCMP_findOffset(pg, FLASH_PAGE_SIZE); + } + pPageInfo->sPage = startHdr.page; + pPageInfo->sOffset = startHdr.pageOffset; + pPageInfo->ePage = endHdr.page; + pPageInfo->eOffset = endHdr.pageOffset; + return (NVINTF_SUCCESS); +} +#else +/****************************************************************************** + * @fn NVOCMP_scanPage + * + * @brief Local function to scan page to get page information + * + * @param pNvHandle - pointer to NV handle + * @param pg - page to scan + * @param pPageInfo - page info pointer + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_scanPage(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, NVOCMP_pageInfo_t * pPageInfo) +{ + uint32_t pageHdr; + NVOCMP_pageHdr_t * pHdr = (NVOCMP_pageHdr_t *) &pageHdr; + + // Get page header + NVOCMP_read(pg, NVOCMP_PGHDROFS, (uint8_t *) pHdr, NVOCMP_PGHDRLEN); + pPageInfo->state = pHdr->state; + pPageInfo->cycle = pHdr->cycle; +#if ((NVOCMP_NVPAGES > NVOCMP_NVONEP) && !defined(NVOCMP_MIGRATE_DISABLED)) + uint8_t version = (pHdr->version << 2) | (pHdr->allActive); + if ((pHdr->signature == NVOCTP_SIGNATURE) && (version == NVOCTP_VERSION)) + { + pPageInfo->allActive = NVOCMP_SOMEINACTIVE; + pPageInfo->mode = NVOCMP_PGNORMAL; + pPageInfo->offset = NVOCMP_findOffset(pg, FLASH_PAGE_SIZE); + } +#endif + if ((pHdr->version == NVOCMP_VERSION) || (pHdr->signature == NVOCMP_SIGNATURE)) + { + pPageInfo->allActive = pHdr->allActive; + if ((pPageInfo->state == NVOCMP_PGNACT) || (pPageInfo->state == NVOCMP_PGXDST) || (pPageInfo->state == NVOCMP_PGRDY)) + { + pPageInfo->offset = NVOCMP_PGDATAOFS; + } + else + { + pPageInfo->offset = NVOCMP_findOffset(pg, FLASH_PAGE_SIZE); + } + } + return (NVINTF_SUCCESS); +} +#endif + +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) +/****************************************************************************** + * @fn NVOCMP_findDstPage + * + * @brief Local function to find dst page after power loss + * + * @param pNvHandle - pointer to NV handle + * + * @return page + */ +static uint8_t NVOCMP_findDstPage(NVOCMP_nvHandle_t * pNvHandle) +{ + uint8_t pg; + for (pg = 0; pg < NVOCMP_NVSIZE; pg++) + { + if (pNvHandle->pageInfo[pg].mode == NVOCMP_PGCDST) + { + return (pg); + } + } + return (NVOCMP_NVSIZE); +} +#endif + +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) +/****************************************************************************** + * @fn NVOCMP_initNv + * + * @brief Local function to init whole NV area + * + * @param pNvHandle - pointer to NV handle + * + * @return none + */ +static void NVOCMP_initNv(NVOCMP_nvHandle_t * pNvHandle) +{ + uint8_t status; + uint8_t pg; + uint8_t tmpPg; + NVOCMP_initAction_t action = NVOCMP_NORMAL_INIT; + NVOCMP_pageInfo_t * pPageInfo; + uint8_t noPgNact = 0; + uint8_t noPgXdst = 0; + uint8_t noPgRdy = 0; + uint8_t noPgAct = 0; + uint8_t noPgFull = 0; + uint8_t noPgXsrc = 0; + uint8_t noPgNdef = 0; + uint16_t pgXdst = NVOCMP_NULLPAGE; + uint16_t pgRdy = NVOCMP_NULLPAGE; + uint16_t pgAct = NVOCMP_NULLPAGE; + uint16_t pgNact = NVOCMP_NULLPAGE; +#if !defined(NVOCMP_MIGRATE_DISABLED) + uint8_t noPgLeg = 0; + uint16_t pgLegAct = NVOCMP_NULLPAGE; + uint16_t pgLegXsrc = NVOCMP_NULLPAGE; +#endif + uint16_t cleanPages = 0; + + // Scan Pages + for (pg = 0; pg < NVOCMP_NVSIZE; pg++) + { + pPageInfo = &pNvHandle->pageInfo[pg]; + status = NVOCMP_scanPage(pNvHandle, pg, pPageInfo); + if (status != NVINTF_SUCCESS) + { + return; + } + if (pPageInfo->state == NVOCMP_PGNACT) + { + noPgNact++; + pgNact = pg; + } + else if (pPageInfo->state == NVOCMP_PGXDST) + { + pgXdst = pg; + noPgXdst++; + } + else if (pPageInfo->state == NVOCMP_PGRDY) + { + pgRdy = pg; + noPgRdy++; + } + else if (pPageInfo->state == NVOCMP_PGACT) + { + pgAct = pg; + noPgAct++; + } + else if (pPageInfo->state == NVOCMP_PGFULL) + { + noPgFull++; + } + else if (pPageInfo->state == NVOCMP_PGXSRC) + { + noPgXsrc++; + } +#if ((NVOCMP_NVPAGES != NVOCMP_NVONEP) && !defined(NVOCMP_MIGRATE_DISABLED)) + else if (pPageInfo->state == NVOCTP_PGACTIVE) + { + pgLegAct = pg; + noPgLeg++; + } + else if (pPageInfo->state == NVOCTP_PGXFER) + { + pgLegXsrc = pg; + noPgLeg++; + } +#endif + else + { + noPgNdef++; + } + } + + // Decide Action based on Page Informations +#if ((NVOCMP_NVPAGES != NVOCMP_NVONEP) && !defined(NVOCMP_MIGRATE_DISABLED)) + if (noPgLeg > 0) + { + action = NVOCMP_NORMAL_MIGRATE; + } + else +#endif + if ((noPgNdef > 0) || (noPgXdst > 1) || (noPgXsrc > 1) || (noPgRdy > 1)) + { + // This should not happen + NVOCMP_ASSERT(false, "Something wrong serious"); + action = NVOCMP_FORCE_CLEAN; + } + else + { + if (noPgNact == NVOCMP_NVSIZE) + { + action = NVOCMP_NORMAL_INIT; + } + else if (noPgXsrc) + { + // Power lost during compaction in progress + if (noPgXdst) + { + action = NVOCMP_RECOVER_COMPACT; + } + // Corrupted due to power lost while writing onto XDST page and erased the XDST page + else if (noPgNact) + { + pgXdst = pgNact; + action = NVOCMP_RECOVER_COMPACT; + } + // Power lost after compaction done, but before erasing PGXSRC page + else + { + if (NVOCMP_findDstPage(pNvHandle) < NVOCMP_NVSIZE) + { + action = NVOCMP_RECOVER_ERASE; + } + else + { + action = NVOCMP_ERROR_UNKNOWN; + } + } + } + else if (noPgXdst) + { + action = NVOCMP_NORMAL_RESUME; + } + else if (noPgAct || noPgFull) + { + if (NVOCMP_findDstPage(pNvHandle) < NVOCMP_NVSIZE) + { + action = NVOCMP_RECOVER_ERASE; + } + else if (noPgNact) + { + pgXdst = pgNact; + NVOCMP_changePageState(pNvHandle, pNvHandle->tailPage, NVOCMP_PGXDST); + action = NVOCMP_NORMAL_RESUME; + } + else + { + action = NVOCMP_ERROR_UNKNOWN; + } + } + else + { + // This case should be considered more + NVOCMP_ASSERT(false, "Something wrong serious"); + action = NVOCMP_FORCE_CLEAN; + } + } + + gAction = action; + + switch (action) + { + case NVOCMP_FORCE_CLEAN: + // Erase All pages before start + for (pg = 0; pg < NVOCMP_NVSIZE; pg++) + { + NVOCMP_failW |= NVOCMP_erase(pNvHandle, pg); + } + // init should be followed by force clean + case NVOCMP_NORMAL_INIT: + // initial state, set head page, act page and tail page + pNvHandle->headPage = 0; + pNvHandle->tailPage = NVOCMP_NVSIZE - 1; + pNvHandle->actPage = 0; + pNvHandle->actOffset = pNvHandle->pageInfo[pNvHandle->actPage].offset; + NVOCMP_changePageState(pNvHandle, pNvHandle->headPage, NVOCMP_PGRDY); + NVOCMP_changePageState(pNvHandle, pNvHandle->tailPage, NVOCMP_PGXDST); + break; + case NVOCMP_NORMAL_RESUME: + // resume state, set head page, act page and tail page + pNvHandle->tailPage = pgXdst; + pNvHandle->headPage = NVOCMP_INCPAGE(pgXdst); + if (pgAct != NVOCMP_NULLPAGE) + { + pNvHandle->actPage = pgAct; + pNvHandle->actOffset = pNvHandle->pageInfo[pgAct].offset; + + NVOCMP_itemHdr_t iHdr; + int8_t status; + if (pNvHandle->actOffset > NVOCMP_PGDATAOFS + NVOCMP_ITEMHDRLEN) + { + NVOCMP_readHeader(pNvHandle->actPage, pNvHandle->actOffset - NVOCMP_ITEMHDRLEN, &iHdr, false); + if (iHdr.stats & NVOCMP_FOLLOWBIT) + { + status = NVOCMP_findItem(pNvHandle, pNvHandle->actPage, pNvHandle->actOffset - NVOCMP_ITEMHDRLEN - iHdr.len, + &iHdr, NVOCMP_FINDSTRICT, NULL); + if ((status == NVINTF_SUCCESS) && (iHdr.hofs > 0)) + { + NVOCMP_setItemInactive(pNvHandle, iHdr.hpage, iHdr.hofs); + } + } + else + { + NVOCMP_compactPage(pNvHandle, 0); + } + } + } + else if (pgRdy != NVOCMP_NULLPAGE) + { + pNvHandle->actPage = pgRdy; + pNvHandle->actOffset = pNvHandle->pageInfo[pgRdy].offset; + } + else + { + pNvHandle->actPage = pNvHandle->headPage; + pNvHandle->actOffset = pNvHandle->pageInfo[pNvHandle->actPage].offset; + } +#ifdef NVOCMP_COMPACT_WHEN_RESUME + NVOCMP_compactPage(pNvHandle, 0); +#endif + break; + case NVOCMP_RECOVER_COMPACT: + pNvHandle->tailPage = pgXdst; + pNvHandle->headPage = NVOCMP_INCPAGE(pgXdst); + NVOCMP_failW = NVOCMP_erase(pNvHandle, pgXdst); + NVOCMP_changePageState(pNvHandle, pgXdst, NVOCMP_PGXDST); + pNvHandle->forceCompact = 1; + NVOCMP_compactPage(pNvHandle, 0); + break; + case NVOCMP_RECOVER_ERASE: + pg = NVOCMP_findDstPage(pNvHandle); + pNvHandle->compactInfo.xDstPage = pg; + pNvHandle->compactInfo.xSrcSPage = pNvHandle->pageInfo[pg].sPage; + pNvHandle->compactInfo.xSrcEPage = pNvHandle->pageInfo[pg].ePage; + cleanPages = NVOCMP_cleanPage(pNvHandle); + pNvHandle->tailPage = NVOCMP_ADDPAGE(pg, cleanPages); + pNvHandle->headPage = NVOCMP_INCPAGE(pNvHandle->tailPage); + + tmpPg = NVOCMP_findPage(NVOCMP_PGACT); + if (tmpPg == NVOCMP_NULLPAGE) + { + tmpPg = NVOCMP_findPage(NVOCMP_PGRDY); + if (tmpPg == NVOCMP_NULLPAGE) + { + tmpPg = NVOCMP_findPage(NVOCMP_PGNACT); + if (tmpPg == NVOCMP_NULLPAGE) + { + tmpPg = NVOCMP_findPage(NVOCMP_PGFULL); + if (tmpPg == NVOCMP_NULLPAGE) + { + tmpPg = pNvHandle->headPage; + } + } + } + } + + pNvHandle->actPage = tmpPg; + pNvHandle->actOffset = pNvHandle->pageInfo[pNvHandle->actPage].offset; + NVOCMP_changePageState(pNvHandle, pNvHandle->tailPage, NVOCMP_PGXDST); + break; +#if !defined(NVOCMP_MIGRATE_DISABLED) + case NVOCMP_NORMAL_MIGRATE: + if (pgLegAct != NVOCMP_NULLPAGE) + { + pNvHandle->actPage = pgLegAct; + } + else + { + pNvHandle->actPage = pgLegXsrc; + } + pNvHandle->headPage = pNvHandle->actPage; + pNvHandle->tailPage = NVOCMP_DECPAGE(pNvHandle->headPage); + pNvHandle->actOffset = pNvHandle->pageInfo[pNvHandle->actPage].offset; + NVOCMP_migratePage(pNvHandle, pNvHandle->actPage); + NVOCMP_compactPage(pNvHandle, 0); + break; +#endif + case NVOCMP_ERROR_UNKNOWN: + /* When this error happens, NV area should be erased to restart. + * This while loop is for only debug purpose */ + NVOCMP_ASSERT1(0); + default: + break; + } +} +#endif +#if (NVOCMP_NVPAGES == NVOCMP_NVTWOP) +/****************************************************************************** + * @fn NVOCMP_initNv + * + * @brief Local function to init whole NV area + * + * @param pNvHandle - pointer to NV handle + * + * @return none + */ +static void NVOCMP_initNv(NVOCMP_nvHandle_t * pNvHandle) +{ + uint8_t status, prevactPage; + NVOCMP_itemHdr_t iHdr; + uint8_t pg; + NVOCMP_initAction_t action; + NVOCMP_pageInfo_t * pPageInfo; + uint16_t pgAct; +#if !defined(NVOCMP_MIGRATE_DISABLED) + uint8_t noPgLeg = 0; +#endif + bool compact = false, compaction_occurred = false; + + // Scan Pages + pNvHandle->xsrcPage = NVOCMP_NULLPAGE; + pNvHandle->tailPage = NVOCMP_NULLPAGE; + + for (pg = 0; pg < NVOCMP_NVSIZE; pg++) + { + pPageInfo = &pNvHandle->pageInfo[pg]; + NVOCMP_scanPage(pNvHandle, pg, pPageInfo); +#if ((NVOCMP_NVPAGES != NVOCMP_NVONEP) && !defined(NVOCMP_MIGRATE_DISABLED)) + if (pPageInfo->state == NVOCTP_PGACTIVE) + { + pNvHandle->actPage = pg; + noPgLeg++; + } + else if (pPageInfo->state == NVOCTP_PGXFER) + { + pNvHandle->xsrcPage = pg; + noPgLeg++; + } + else +#endif + if ((pPageInfo->state == NVOCMP_PGACT) || (pPageInfo->state == NVOCMP_PGFULL)) + { + pNvHandle->actPage = pg; + } + else if (pPageInfo->state == NVOCMP_PGXSRC) + { + pNvHandle->xsrcPage = pg; + } + else if (pPageInfo->state == NVOCMP_PGXDST) + { + pNvHandle->tailPage = pg; + } + } + + action = NVOCMP_NORMAL_INIT; + // Decide Action based on Page Informations +#if ((NVOCMP_NVPAGES != NVOCMP_NVONEP) && !defined(NVOCMP_MIGRATE_DISABLED)) + if (noPgLeg > 0) + { + action = NVOCMP_NORMAL_MIGRATE; + } + else + { +#endif + if (pNvHandle->actPage != NVOCMP_NULLPAGE) + { + action = NVOCMP_NORMAL_RESUME; + } + else if (pNvHandle->xsrcPage != NVOCMP_NULLPAGE) + { + pNvHandle->actPage = pNvHandle->xsrcPage; + action = NVOCMP_RECOVER_COMPACT; + } + else if (pNvHandle->tailPage != NVOCMP_NULLPAGE) + { + pgAct = NVOCMP_INCPAGE(pNvHandle->tailPage); + if (pNvHandle->pageInfo[pgAct].offset) + { + pNvHandle->actPage = pgAct; + action = NVOCMP_RECOVER_COMPACT; + } + else + { + pNvHandle->tailPage = NVOCMP_NULLPAGE; + } + } + + if (pNvHandle->actPage == NVOCMP_NULLPAGE) + { + pNvHandle->actPage = 0; + NVOCMP_failW |= NVOCMP_erase(pNvHandle, 0); + NVOCMP_changePageState(pNvHandle, 0, NVOCMP_PGRDY); + } + + if (pNvHandle->tailPage == NVOCMP_NULLPAGE) + { + pNvHandle->tailPage = NVOCMP_INCPAGE(pNvHandle->actPage); + ; + NVOCMP_failW |= NVOCMP_erase(pNvHandle, pNvHandle->tailPage); + NVOCMP_changePageState(pNvHandle, pNvHandle->tailPage, NVOCMP_PGXDST); + } + + pNvHandle->headPage = pNvHandle->actPage; + pNvHandle->actOffset = pNvHandle->pageInfo[pNvHandle->actPage].offset; +#if ((NVOCMP_NVPAGES != NVOCMP_NVONEP) && !defined(NVOCMP_MIGRATE_DISABLED)) + } +#endif + + gAction = action; + + switch (action) + { + case NVOCMP_NORMAL_RESUME: + // resume state, set head page, act page and tail page + do + { + compaction_occurred = false; + if (pNvHandle->actOffset > NVOCMP_PGDATAOFS + NVOCMP_ITEMHDRLEN) + { + NVOCMP_readHeader(pNvHandle->actPage, pNvHandle->actOffset - NVOCMP_ITEMHDRLEN, &iHdr, false); + if (iHdr.stats & NVOCMP_FOLLOWBIT) + { + /* Cache current active page value before search starts */ + prevactPage = pNvHandle->actPage; + status = NVOCMP_findItem(pNvHandle, pNvHandle->actPage, pNvHandle->actOffset - NVOCMP_ITEMHDRLEN - iHdr.len, + &iHdr, NVOCMP_FINDSTRICT, NULL); + + /* If the current active page is different than previous, then + * compaction occurred and the search for duplicate must occur + * again. + * If item is found and compaction did not occur, it is a true + * duplicate, so the item can be deleted. */ + compaction_occurred = (prevactPage != pNvHandle->actPage); + if ((status == NVINTF_SUCCESS) && (iHdr.hofs > 0) && !compaction_occurred) + { + NVOCMP_setItemInactive(pNvHandle, iHdr.hpage, iHdr.hofs); + } + } + else + { + pNvHandle->forceCompact = 1; + compact = true; + } + } + } while (compaction_occurred); /* Repeat until compaction does not occur while searching */ +#ifdef NVOCMP_COMPACT_WHEN_RESUME + compact = true; +#endif + break; +#if !defined(NVOCMP_MIGRATE_DISABLED) + case NVOCMP_NORMAL_MIGRATE: + if (pNvHandle->actPage == NVOCMP_NULLPAGE) + { + pNvHandle->actPage = pNvHandle->xsrcPage; + } + pNvHandle->headPage = pNvHandle->actPage; + pNvHandle->tailPage = NVOCMP_DECPAGE(pNvHandle->headPage); + pNvHandle->actOffset = pNvHandle->pageInfo[pNvHandle->actPage].offset; + NVOCMP_failW = NVOCMP_erase(pNvHandle, pNvHandle->tailPage); + NVOCMP_migratePage(pNvHandle, pNvHandle->actPage); + compact = true; + break; +#endif + case NVOCMP_RECOVER_COMPACT: + pNvHandle->forceCompact = 1; + compact = true; + break; + default: + break; + } + + if (compact) + { + NVOCMP_compactPage(pNvHandle, 0); + } +} +#endif + +#if (NVOCMP_NVPAGES == NVOCMP_NVONEP) +/****************************************************************************** + * @fn NVOCMP_initNv + * + * @brief Local function to init whole NV area + * + * @param pNvHandle - pointer to NV handle + * + * @return none + */ +static void NVOCMP_initNv(NVOCMP_nvHandle_t * pNvHandle) +{ + uint8_t status; + NVOCMP_itemHdr_t iHdr; + NVOCMP_initAction_t action; + NVOCMP_pageInfo_t * pPageInfo; + bool compact = false; + + // Scan Pages + pNvHandle->xsrcPage = NVOCMP_NULLPAGE; + pNvHandle->tailPage = NVOCMP_NULLPAGE; + + pPageInfo = &pNvHandle->pageInfo[0]; + NVOCMP_scanPage(pNvHandle, 0, pPageInfo); + if ((pPageInfo->state == NVOCMP_PGACT) || (pPageInfo->state == NVOCMP_PGFULL)) + { + pNvHandle->actPage = 0; + } + else if (pPageInfo->state == NVOCMP_PGXSRC) + { + pNvHandle->xsrcPage = 0; + } + + action = NVOCMP_NORMAL_INIT; + // Decide Action based on Page Informations + if (pNvHandle->actPage != NVOCMP_NULLPAGE) + { + action = NVOCMP_NORMAL_RESUME; + } + else if (pNvHandle->xsrcPage != NVOCMP_NULLPAGE) + { + pNvHandle->actPage = 0; + action = NVOCMP_RECOVER_COMPACT; + } + + if (pNvHandle->actPage == NVOCMP_NULLPAGE) + { + pNvHandle->actPage = 0; + NVOCMP_failW |= NVOCMP_erase(pNvHandle, 0); + NVOCMP_changePageState(pNvHandle, 0, NVOCMP_PGRDY); + } + + pNvHandle->tailPage = 0; + pNvHandle->headPage = 0; + pNvHandle->actOffset = pNvHandle->pageInfo[0].offset; + + gAction = action; + + switch (action) + { + case NVOCMP_NORMAL_RESUME: + // resume state, set head page, act page and tail page + if (pNvHandle->actOffset > NVOCMP_PGDATAOFS + NVOCMP_ITEMHDRLEN) + { + NVOCMP_readHeader(pNvHandle->actPage, pNvHandle->actOffset - NVOCMP_ITEMHDRLEN, &iHdr, false); + if (iHdr.stats & NVOCMP_FOLLOWBIT) + { + status = NVOCMP_findItem(pNvHandle, pNvHandle->actPage, pNvHandle->actOffset - NVOCMP_ITEMHDRLEN - iHdr.len, &iHdr, + NVOCMP_FINDSTRICT, NULL); + if ((status == NVINTF_SUCCESS) && (iHdr.hofs > 0)) + { + NVOCMP_setItemInactive(pNvHandle, iHdr.hpage, iHdr.hofs); + } + } + else + { + pNvHandle->forceCompact = 1; + compact = true; + } + } +#ifdef NVOCMP_COMPACT_WHEN_RESUME + compact = true; +#endif + break; + case NVOCMP_RECOVER_COMPACT: + pNvHandle->forceCompact = 1; + compact = true; + break; + default: + break; + } + + if (compact) + { + NVOCMP_compactPage(pNvHandle, 0); + } +} +#endif + +/****************************************************************************** + * @fn NVOCMP_checkItem + * + * @brief Local function to check parameters and locate existing item + * + * @param id - NV item type identifier + * @param len - NV item data length + * @param pHdr - pointer to header buffer + * @param flag - flag for item search + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_checkItem(NVINTF_itemID_t * id, uint16_t len, NVOCMP_itemHdr_t * pHdr, uint8_t flag) +{ + if (len > NVOCMP_MAXLEN) + { + // Item data is too long + NVOCMP_ALERT(false, "Item data too large.") + return (NVINTF_BADLENGTH); + } + if (id->systemID > NVOCMP_MAXSYSID) + { + // Too large for compressed header + NVOCMP_ALERT(false, "Item sysid too large.") + return (NVINTF_BADSYSID); + } + if (id->itemID > NVOCMP_MAXITEMID) + { + // Too large for compressed header + NVOCMP_ALERT(false, "Item itemid too large.") + return (NVINTF_BADITEMID); + } + if (id->subID > NVOCMP_MAXSUBID) + { + // Too large for compressed header + NVOCMP_ALERT(false, "Item subid too large.") + return (NVINTF_BADSUBID); + } + + if (NVOCMP_failF == NVINTF_NOTREADY) + { + // NV driver has not been initialized + NVOCMP_ASSERT(false, "Driver uninitialized.") + return (NVINTF_NOTREADY); + } + + pHdr->len = len; + pHdr->hofs = 0; + pHdr->cmpid = NVOCMP_CMPRID(id->systemID, id->itemID, id->subID); + pHdr->subid = id->subID; + pHdr->itemid = id->itemID; + pHdr->sysid = id->systemID; + pHdr->sig = NVOCMP_SIGNATURE; + + return (NVINTF_SUCCESS); +} + +/****************************************************************************** + * @fn NVOCMP_getDstPage + * + * @brief Local function to find the page where an item will be written on + * + * @param pNvHandle - pointer to NV handle + * @param len - item size to write + * + * @return page number or NVOCMP_NULLPAGE + */ +static uint8_t NVOCMP_getDstPage(NVOCMP_nvHandle_t * pNvHandle, uint16_t len) +{ + uint8_t dstPg = NVOCMP_NULLPAGE; + uint8_t pg = pNvHandle->actPage; + NVOCMP_pageHdr_t pageHdr; +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) + uint16_t nvSearched = 0; + for (pg = pNvHandle->actPage; nvSearched < NVOCMP_NVSIZE; pg = NVOCMP_INCPAGE(pg)) + { + nvSearched++; + if (pg == pNvHandle->tailPage) + { + continue; + } +#endif + NVOCMP_read(pg, NVOCMP_PGHDROFS, (uint8_t *) &pageHdr, NVOCMP_PGHDRLEN); + if (pageHdr.state == NVOCMP_PGFULL) + { +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) + continue; +#else + return (dstPg); +#endif + } + if ((pageHdr.state == NVOCMP_PGNACT) || (pageHdr.state == NVOCMP_PGRDY)) + { + NVOCMP_changePageState(pNvHandle, pg, NVOCMP_PGACT); + } + + pNvHandle->actPage = pg; + pNvHandle->actOffset = pNvHandle->pageInfo[pg].offset; + if ((pNvHandle->pageInfo[pg].offset + len) <= FLASH_PAGE_SIZE) + { + dstPg = pNvHandle->actPage; +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) + break; +#endif + } + else + { + NVOCMP_changePageState(pNvHandle, pg, NVOCMP_PGFULL); + } +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) + } +#endif + return (dstPg); +} + +/****************************************************************************** + * @fn NVOCMP_addItem + * + * @brief Local function to check for adequate space and create a new item + * + * @param pNvHandle - pointer to NV handle + * @param iHdr - pointer to header buffer + * @param pBuf - pointer to item + * @param wm - write mode + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_addItem(NVOCMP_nvHandle_t * pNvHandle, NVOCMP_itemHdr_t * iHdr, uint8_t * pBuf, NVOCMP_writeMode_t wm) +{ + uint8_t err; + uint8_t dstPg; + uint16_t iLen; + bool compact = false; + NVOCMP_itemHdr_t hdr; + + iLen = NVOCMP_ITEMHDRLEN + iHdr->len; + dstPg = NVOCMP_getDstPage(pNvHandle, iLen); + + if (dstPg == NVOCMP_NULLPAGE) + { + compact = true; + // Won't fit on the active page, compact and check again + if (NVOCMP_compactPage(pNvHandle, iLen) < iLen) + { + // Failure means there's no place to put this item + NVOCMP_ALERT(false, "Out of NV.") + err = (NVOCMP_failW != NVINTF_SUCCESS) ? NVOCMP_failW : NVINTF_BADLENGTH; + return (err); + } + } + + if ((NVOCMP_failW == NVINTF_SUCCESS) && ((wm == NVOCMP_WRITE) || ((wm == NVOCMP_UPDATE) && (compact == true)))) + { + /* get item offset after compaction */ + hdr.sysid = iHdr->sysid; + hdr.itemid = iHdr->itemid; + hdr.subid = iHdr->subid; + (void) NVOCMP_findItem(pNvHandle, pNvHandle->actPage, pNvHandle->actOffset, &hdr, NVOCMP_FINDSTRICT, NULL); + iHdr->hpage = hdr.hpage; + iHdr->hofs = hdr.hofs; + } + +#if NVOCMP_NWSAMEITEM + bool changed = false; + if ((iHdr->hofs) && (iHdr->len)) + { +#define NVOCMP_COMPARE_SIZE 32 + uint8_t readBuf[NVOCMP_COMPARE_SIZE]; + uint16_t iOfs = (iHdr->hofs - iHdr->len); + uint16_t dOfs = 0; + uint16_t len2cmp = 0; + + // Failure to parse the command + NVOCMP_ALERT(iHdr->hofs >= iHdr->len, "Something wrong in parsing.") + + do + { + len2cmp = (iHdr->len - dOfs) > NVOCMP_COMPARE_SIZE ? NVOCMP_COMPARE_SIZE : (iHdr->len - dOfs); + NVOCMP_read(iHdr->hpage, iOfs + dOfs, readBuf, len2cmp); + if (memcmp(readBuf, pBuf + dOfs, len2cmp)) + { + changed = true; + break; + } + dOfs += len2cmp; + } while (dOfs < iHdr->len); + } + else + { + changed = true; + } + + if (changed) + { + // Create the new NV item + NVOCMP_writeItem(pNvHandle, iHdr, pNvHandle->actPage, pNvHandle->actOffset, pBuf); + } + else + { + iHdr->hofs = 0; + } +#else + // Create the new NV item + NVOCMP_writeItem(pNvHandle, iHdr, pNvHandle->actPage, pNvHandle->actOffset, pBuf); +#endif + + // Status of writing/erasing Flash + return (NVOCMP_failW); +} + +/****************************************************************************** + * @fn NVOCMP_read + * + * @brief Writes to a flash buffer from RAM + * + * @param pg - Flash page to write from + * @param off - Offset in destination page to read from + * @param pBuf - Pointer to write the results into + * @param len - Number of bytes to write into + * + * @return NVS_STATUS_SUCCESS or other NVS status code + */ +static inline void NVOCMP_read(uint8_t pg, uint16_t off, uint8_t * pBuf, uint16_t len) +{ +#ifndef NV_LINUX + NVS_read(NVOCMP_nvsHandle, NVOCMP_FLASHOFFSET(pg, off), (uint8_t *) pBuf, len); +#else + NV_LINUX_read(pg, off, pBuf, len); +#endif +} + +/****************************************************************************** + * @fn NVOCMP_write + * + * @brief Writes to a flash buffer from RAM + * + * @param dstPg - Flash page to write to + * @param off - offset in destination page to write to + * @param pBuf - Pointer to caller's buffer to write & verify + * @param len - number of bytes to write from pBuf + * + * @return NVS_STATUS_SUCCESS or other NVS status code + */ +static uint8_t NVOCMP_write(uint8_t dstPg, uint16_t off, uint8_t * pBuf, uint16_t len) +{ + uint8_t err = NVINTF_SUCCESS; + int_fast16_t nvsRes = 0; + + // check voltage if possible + NVOCMP_FLASHACCESS(err) + + if (NVINTF_SUCCESS == err) + { +#ifndef NV_LINUX + nvsRes = NVS_write(NVOCMP_nvsHandle, NVOCMP_FLASHOFFSET(dstPg, off), pBuf, len, NVS_WRITE_POST_VERIFY); +#else + nvsRes = NV_LINUX_write(dstPg, off, pBuf, len); +#endif + } + else + { + err = NVINTF_LOWPOWER; + } + + if (nvsRes < 0) + { + err = NVINTF_FAILURE; + } + + NVOCMP_ALERT(NVINTF_LOWPOWER != err, "Voltage check failed.") + if (NVINTF_FAILURE == err) + { + NVOCMP_ALERT(NVINTF_FAILURE != err, "NVS write failure.") + } + + return (err); +} + +/****************************************************************************** + * @fn NVOCMP_erase + * + * @brief Erases a flash page + * + * @param pNvHandle - pointer to NV handle + * @param dstPg - Flash page to write to + * + * @return NVINT_SUCCESS or other NVINTF status code + */ +static uint8_t NVOCMP_erase(NVOCMP_nvHandle_t * pNvHandle, uint8_t dstPg) +{ + uint8_t err = NVINTF_SUCCESS; + int_fast16_t nvsRes = 0; + + // Check voltage if possible + NVOCMP_FLASHACCESS(err) + + if (NVINTF_SUCCESS == err) + { +#ifndef NV_LINUX + nvsRes = NVS_erase(NVOCMP_nvsHandle, NVOCMP_FLASHOFFSET(dstPg, 0), NVOCMP_nvsAttrs.sectorSize); +#else + nvsRes = NV_LINUX_erase(dstPg); +#endif + if (nvsRes < 0) + { + err = NVINTF_FAILURE; + } + else + { + // Bump the compaction cycle counter, wrap-around if at maximum + pNvHandle->pageInfo[dstPg].cycle = + (pNvHandle->pageInfo[dstPg].cycle < NVOCMP_MAXCYCLE) ? (pNvHandle->pageInfo[dstPg].cycle + 1) : NVOCMP_MINCYCLE; + NVOCMP_setPageState(pNvHandle, dstPg, NVOCMP_PGNACT); + NVOCMP_setCompactHdr(dstPg, NVOCMP_NULLPAGE, NVOCMP_NULLOFFSET, THISPAGEHDR); + NVOCMP_setCompactHdr(dstPg, NVOCMP_NULLPAGE, NVOCMP_NULLOFFSET, XSRCSTARTHDR); + NVOCMP_setCompactHdr(dstPg, NVOCMP_NULLPAGE, NVOCMP_NULLOFFSET, XSRCENDHDR); + pNvHandle->pageInfo[dstPg].offset = NVOCMP_PGDATAOFS; + pNvHandle->pageInfo[dstPg].mode = NVOCMP_PGNORMAL; + } + } + else + { + err = NVINTF_LOWPOWER; + } + + NVOCMP_ALERT(NVINTF_LOWPOWER != err, "Voltage check failed.") + NVOCMP_ALERT(NVINTF_FAILURE != err, "NVS erase failure.") + + return (err); +} + +/****************************************************************************** + * @fn NVOCMP_writeItem + * + * @brief Write entire NV item to new location on active Flash page. + * Each call to NVS_write() does a read-back to verify. If an + * error is detected, the 'failW' flag is set to inhibit further + * flash write attempts until the next NV transaction. + * + * @param pNvHandle - pointer to NV handle + * @param pHdr - Pointer to caller's item header buffer + * @param dstPg - Destination NV Flash page + * @param dstOff - Destination offset + * @param pBuf - Points to buffer which will be written to item + * + * @return none + */ +static void NVOCMP_writeItem(NVOCMP_nvHandle_t * pNvHandle, NVOCMP_itemHdr_t * pHdr, uint8_t dstPg, uint16_t dstOff, uint8_t * pBuf) +{ + uint16_t iLen; + NVOCMP_pageHdr_t pageHdr; + + NVOCMP_read(dstPg, NVOCMP_PGHDROFS, (uint8_t *) &pageHdr, NVOCMP_PGHDRLEN); + if (pageHdr.state == NVOCMP_PGRDY) + { + NVOCMP_changePageState(pNvHandle, dstPg, NVOCMP_PGACT); + } + + if (pageHdr.state != NVOCMP_PGACT) + { + NVOCMP_failW = NVINTF_FAILURE; + return; + } + + NVOCMP_ALERT(pageHdr.state == NVOCMP_PGACT, "Something wrong.") + + // Total length of this item + iLen = NVOCMP_ITEMHDRLEN + pHdr->len; + + if ((dstOff + iLen) <= FLASH_PAGE_SIZE) + { + cmpIH_t cHdr; + uint16_t hOfs, dLen; + uint8_t newCRC; + + // Compressed item header information <-- Lower Addr Higher Addr--> + // Byte: [0] [1] [2] [3] [4] [5] [6] + // Item: SSSSSSII IIIIIIII SSSSSSSS SSLLLLLL LLLLLLCC CCCCCCAV SSSSSSSS + // LSB of field: ^ ^ ^ ^ ^ +#if NVOCMP_HDRLE + cHdr[0] = (pHdr->sysid & 0x3F) | ((pHdr->itemid & 0x3) << 6); + cHdr[1] = (pHdr->itemid >> 2) & 0xFF; + cHdr[2] = pHdr->subid & 0xFF; + cHdr[3] = ((pHdr->subid >> 8) & 0x3) | ((pHdr->len & 0x3F) << 2); + cHdr[4] = (pHdr->len >> 6) & 0x3F; +#else + cHdr[0] = ((pHdr->sysid << 2) | ((pHdr->itemid >> 8) & 0x3)); + cHdr[1] = (pHdr->itemid & 0xFF); + cHdr[2] = ((pHdr->subid >> 2) & 0xFF); + cHdr[3] = ((pHdr->subid & 0x3) << 6) | ((pHdr->len >> 6) & 0x3F); + cHdr[4] = ((pHdr->len & 0x3F) << 2); +#endif + // Header is located after the item data + dLen = pHdr->len; + hOfs = dstOff + dLen; + + if (iLen <= NVOCMP_SMALLITEM) + { + // Construct item in one buffer + // Put data into buffer + memcpy(NVOCMP_itemBuffer, (const void *) pBuf, dLen); + // Put most of header into buffer + memcpy(NVOCMP_itemBuffer + dLen, (const void *) cHdr, NVOCMP_HDRCRCINC); + // Calculate CRC + newCRC = NVOCMP_doRAMCRC(NVOCMP_itemBuffer, dLen + NVOCMP_HDRCRCINC, 0); +#if NVOCMP_HDRLE + // Insert CRC and last bytes + cHdr[4] |= ((newCRC & 0x3) << 6); + // Note NVOCMP_VALIDIDBIT set implicitly zero + cHdr[5] = ((newCRC >> 2) & 0x3F) | (NVOCMP_ACTIVEIDBIT << 6); +#else + // Insert CRC and last bytes + cHdr[4] |= ((newCRC >> 6) & 0x3); + // Note NVOCMP_VALIDIDBIT set implicitly zero + cHdr[5] = ((newCRC & 0x3F) << 2) | NVOCMP_ACTIVEIDBIT; +#endif + cHdr[6] = NVOCMP_SIGNATURE; + memcpy(NVOCMP_itemBuffer + dLen, (const void *) cHdr, NVOCMP_ITEMHDRLEN); + // NVS_write + NVOCMP_failW = NVOCMP_write(dstPg, dstOff, NVOCMP_itemBuffer, iLen); + // Advance to next location + dstOff += iLen; + pNvHandle->actOffset += iLen; + pNvHandle->pageInfo[dstPg].offset = dstOff; + } + else + { + // Write header/item separately + // Calculate CRC on data portion + newCRC = NVOCMP_doRAMCRC(pBuf, dLen, 0); + // Finish CRC using header portion + newCRC = NVOCMP_doRAMCRC(cHdr, NVOCMP_HDRCRCINC, newCRC); + // Complete Header with CRC, bits, and sig +#if NVOCMP_HDRLE + // Insert CRC and last bytes + cHdr[4] |= ((newCRC & 0x3) << 6); + // Note NVOCMP_VALIDIDBIT set implicitly zero + cHdr[5] = ((newCRC >> 2) & 0x3F) | (NVOCMP_ACTIVEIDBIT << 6); +#else + // Insert CRC and last bytes + cHdr[4] |= ((newCRC >> 6) & 0x3); + // Note NVOCMP_VALIDIDBIT set implicitly zero + cHdr[5] = ((newCRC & 0x3F) << 2) | NVOCMP_ACTIVEIDBIT; +#endif + cHdr[6] = NVOCMP_SIGNATURE; + // Write data + NVOCMP_failW = NVOCMP_write(dstPg, dstOff, pBuf, dLen); + // Write header + NVOCMP_failW |= NVOCMP_write(dstPg, hOfs, cHdr, NVOCMP_ITEMHDRLEN); + // Advance to next location + NVOCMP_ASSERT(dstOff < (dstOff + iLen), "Page offset overflow!") + if (!NVOCMP_failW) + { + dstOff += iLen; + pNvHandle->actOffset += iLen; + pNvHandle->pageInfo[dstPg].offset = dstOff; + } + else + { + return; + } + } + // If there was a write failure, delete item + NVOCMP_ALERT(!NVOCMP_failW, "Driver write failure. Item deleted.") + if (NVOCMP_failW) + { + NVOCMP_setItemInactive(pNvHandle, dstPg, hOfs); + } + } + else + { + // Not enough room on page + NVOCMP_failW = NVINTF_BADLENGTH; + } +} + +/****************************************************************************** + * @fn NVOCMP_readHeader + * + * @brief Read header block from NV and expand into caller's buffer + * + * @param pg - A valid NV Flash page + * @param ofs - A valid offset into the page + * @param pHdr - Pointer to caller's item header buffer + * @param flag - fast flag (not used if NVOCMP_RAM_OPTIMIZATION is defined) + * + * @return none + */ +static void NVOCMP_readHeader(uint8_t pg, uint16_t ofs, NVOCMP_itemHdr_t * pHdr, bool flag) +{ +#ifndef NVOCMP_RAM_OPTIMIZATION +#ifdef NVOCMP_GPRAM + uint8_t * pTBuffer = RAM_BUFFER_ADDRESS; +#else + uint8_t * pTBuffer = (uint8_t *) tBuffer; +#endif +#endif + + cmpIH_t cHdr; +#ifndef NVOCMP_RAM_OPTIMIZATION + if (flag) + { + memcpy((uint8_t *) cHdr, (uint8_t *) (pTBuffer + ofs), NVOCMP_ITEMHDRLEN); + } + else + { +#endif + // Get item header from Flash + NVOCMP_read(pg, ofs, (uint8_t *) cHdr, NVOCMP_ITEMHDRLEN); +#ifndef NVOCMP_RAM_OPTIMIZATION + } +#endif + // Offset to compressed header + pHdr->hofs = ofs; + pHdr->hpage = pg; + + // Compressed item header information <-- Lower Addr Higher Addr--> + // Byte: [0] [1] [2] [3] [4] [5] [6] + // Item: SSSSSSII IIIIIIII SSSSSSSS SSLLLLLL LLLLLLCC CCCCCCAV SSSSSSSS + // LSB of field: ^ ^ ^ ^ ^ +#if NVOCMP_HDRLE + pHdr->sysid = cHdr[0] & 0x3F; + pHdr->itemid = ((cHdr[0] >> 6) & 0x3) | (cHdr[1] << 2); + pHdr->subid = cHdr[2] | ((cHdr[3] & 0x3) << 8); + pHdr->len = ((cHdr[3] >> 2) & 0x3F) | ((cHdr[4] & 0x3F) << 6); + pHdr->crc8 = ((cHdr[4] >> 6) & 0x3) | ((cHdr[5] & 0x3F) << 2); + pHdr->stats = (cHdr[5] >> 6) & (NVOCMP_VALIDIDBIT | NVOCMP_ACTIVEIDBIT); + pHdr->sig = cHdr[6]; +#else + pHdr->sysid = (cHdr[0] >> 2) & 0x3F; + pHdr->itemid = ((cHdr[0] & 0x3) << 8) | cHdr[1]; + pHdr->subid = (cHdr[2] << 2) | ((cHdr[3] >> 6) & 0x3); + pHdr->len = ((cHdr[3] & 0x3F) << 6) | ((cHdr[4] >> 2) & 0x3F); + pHdr->crc8 = ((cHdr[4] & 0x3) << 6) | ((cHdr[5] >> 2) & 0x3F); + pHdr->stats = cHdr[5] & (NVOCMP_VALIDIDBIT | NVOCMP_ACTIVEIDBIT); + pHdr->sig = cHdr[6]; +#endif + pHdr->cmpid = NVOCMP_CMPRID(pHdr->sysid, pHdr->itemid, pHdr->subid); + // Our item has correct signature? + if (pHdr->sig != NVOCMP_SIGNATURE) + { + // Indicate item is invalid + NVOCMP_ALERT(false, "Invalid signature detected! Item corrupted.") + pHdr->stats |= NVOCMP_VALIDIDBIT; + } + else + { + (pHdr->stats) |= NVOCMP_FOLLOWBIT; + NVOCMP_ALERT(pHdr->stats & NVOCMP_FOLLOWBIT, "Item gap detected. Item not followed.") + } +} + +/****************************************************************************** + * @fn NVOCMP_readItem + * + * @brief Function to read an item described by iHdr into pBuf + * + * @param iHdr - pointer to an item header struct + * @param bOfs - offset into NV data block + * @param len - length of NV data to return (0 is illegal) + * @param pBuf - pointer to caller's read data buffer (NULL is illegal) + * @param flag - fast flag (not used if NVOCMP_RAM_OPTIMIZATION is defined) + * + * @return NVINTF_SUCCESS or specific failure code + */ +static uint8_t NVOCMP_readItem(NVOCMP_itemHdr_t * iHdr, uint16_t ofs, uint16_t len, void * pBuf, bool flag) +{ + uint8_t err = NVINTF_SUCCESS; + uint16_t dOfs, iOfs; +#ifndef NVOCMP_RAM_OPTIMIZATION +#ifdef NVOCMP_GPRAM + uint8_t * pTBuffer = RAM_BUFFER_ADDRESS; +#else + uint8_t * pTBuffer = (uint8_t *) tBuffer; +#endif +#endif + iOfs = (iHdr->hofs - iHdr->len); + + // Optional CRC integrity check +#if NVOCMP_CRCONREAD + err = NVOCMP_verifyCRC(iOfs, iHdr->len, iHdr->crc8, iHdr->hpage, flag); +#endif + + if (err == NVINTF_SUCCESS) + { + // Offset to start of item data + dOfs = iOfs + ofs; + if ((dOfs + len) <= iHdr->hofs) + { +#ifndef NVOCMP_RAM_OPTIMIZATION + if (flag) + { + // Copy from RAM + memcpy((uint8_t *) pBuf, (uint8_t *) (pTBuffer + dOfs), len); + } + else + { +#endif + // Copy NV data block to caller's buffer + NVOCMP_read(iHdr->hpage, dOfs, (uint8_t *) pBuf, len); +#ifndef NVOCMP_RAM_OPTIMIZATION + } +#endif + } + else + { + // Bad length or offset + err = (len > iHdr->len) ? NVINTF_BADLENGTH : NVINTF_BADOFFSET; + } + } + + return (err); +} + +/****************************************************************************** + * @fn NVOCMP_setItemInactive + * + * @brief Mark an item as inactive + * + * @param pNvHandle - pointer to NV handle + * @param pg - page where the item is located + * @param iOfs - Offset to item header (lowest address) in active page + * + * @return none + */ +static void NVOCMP_setItemInactive(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, uint16_t iOfs) +{ + uint8_t tmp; + + // Get byte with validity bit + tmp = NVOCMP_readByte(pg, iOfs + NVOCMP_HDRVLDOFS); + + // Remove ACTIVE_IDS_MARK +#if NVOCMP_HDRLE + tmp &= ~(NVOCMP_ACTIVEIDBIT << 6); +#else + tmp &= ~NVOCMP_ACTIVEIDBIT; +#endif + // Mark the item as inactive + NVOCMP_writeByte(pg, iOfs + NVOCMP_HDRVLDOFS, tmp); + + if (pNvHandle->pageInfo[pg].allActive) + { + tmp = NVOCMP_readByte(pg, NVOCMP_PGHDRVER); + tmp &= ~NVOCMP_ALLACTIVE; + NVOCMP_writeByte(pg, NVOCMP_PGHDRVER, tmp); + pNvHandle->pageInfo[pg].allActive = NVOCMP_SOMEINACTIVE; + } +} + +/****************************************************************************** + * @fn NVOCMP_setCompactHdr + * + * @brief Set compact header + * + * @param dstPg - destination page to write the header + * @param pg - page of compaction + * @param offset - offset of compaction + * @param location - location of the header + * + * @return none + */ +static void NVOCMP_setCompactHdr(uint8_t dstPg, uint8_t pg, int16_t offset, uint16_t location) +{ + NVOCMP_compactHdr_t hdr = DEFAULT_COMPACTHDR; + hdr.page = pg; + hdr.pageOffset = offset; + + NVOCMP_failW = NVOCMP_write(dstPg, (location + 1) * NVOCMP_COMPACTHDRLEN, (uint8_t *) &hdr, NVOCMP_COMPACTHDRLEN); +} + +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) +/****************************************************************************** + * @fn NVOCMP_getCompactHdr + * + * @brief Get compact header + * + * @param dstPg - destination page to read the header + * @param location - location of the header + * @param pHdr - pointer to the header + * + * @return none + */ +static void NVOCMP_getCompactHdr(uint8_t dstPg, uint16_t location, NVOCMP_compactHdr_t * pHdr) +{ + NVOCMP_read(dstPg, (location + 1) * NVOCMP_COMPACTHDRLEN, (uint8_t *) pHdr, NVOCMP_COMPACTHDRLEN); +} +#endif + +/****************************************************************************** + * @fn NVOCMP_setPageState + * + * @brief Set specified NV page state + * + * @param pNvHandle - pointer to NV handle + * @param pg - target NV page + * @param state - state of the page + * + * @return none + */ +static void NVOCMP_setPageState(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, NVOCMP_pageState_t state) +{ + NVOCMP_pageHdr_t pHdr; + + // Load header + pHdr.state = (uint8_t) state; + pHdr.cycle = (uint8_t) pNvHandle->pageInfo[pg].cycle; + pHdr.allActive = NVOCMP_ALLACTIVE; + pHdr.version = (uint8_t) NVOCMP_VERSION; + pHdr.signature = (uint8_t) NVOCMP_SIGNATURE; + + // Write to page + NVOCMP_failW = NVOCMP_write(pg, 0, (uint8_t *) &pHdr, NVOCMP_PGHDRLEN); + + if (NVOCMP_failW == NVINTF_SUCCESS) + { + if (state == NVOCMP_PGACT) + { + // No errors, switch active page + pNvHandle->actPage = pg; + } + pNvHandle->pageInfo[pg].state = state; + pNvHandle->pageInfo[pg].allActive = NVOCMP_ALLACTIVE; + } +} + +/****************************************************************************** + * @fn NVOCMP_changePageState + * + * @brief Change NV page state + * + * @param pNvHandle - pointer to NV handle + * @param pg - target NV page + * @param state - state of the page + * + * @return none + */ +static void NVOCMP_changePageState(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, NVOCMP_pageState_t state) +{ + NVOCMP_writeByte(pg, NVOCMP_PGHDROFS, (uint8_t) state); + + if (NVOCMP_failW == NVINTF_SUCCESS) + { + if (state == NVOCMP_PGACT) + { + // No errors, switch active page + pNvHandle->actPage = pg; + } + pNvHandle->pageInfo[pg].state = state; + } +} + +/****************************************************************************** + * @fn NVOCMP_findOffset + * + * @brief Find the offset to next available empty space in specified page + * + * @param pg - Valid NV page on which to find offset to next available data + * @param ofs - Beginning offset to start search + * + * @return Number of bytes from start of page to next available item location + */ +#if NVOCMP_FASTOFF +static uint16_t NVOCMP_findOffset(uint8_t pg, uint16_t ofs) +{ + uint8_t i, j; + uint32_t * tmp; +#ifdef NVOCMP_GPRAM + uint32_t vm; + uint8_t * pTBuffer = RAM_BUFFER_ADDRESS; +#else + uint8_t * pTBuffer = (uint8_t *) tBuffer; +#endif + +#ifdef NVOCMP_GPRAM + NVOCMP_disableCache(&vm); +#endif + + NVOCMP_read(pg, 0, (uint8_t *) pTBuffer, FLASH_PAGE_SIZE); + + // Find first non-erased 4-byte location + tmp = (uint32_t *) pTBuffer; + while (ofs >= sizeof(uint32_t)) + { + ofs -= sizeof(uint32_t); + tmp = (uint32_t *) (pTBuffer + ofs); + if ((*tmp) != NVOCMP_ERASEDWORD) + { + break; + } + } + + // Starting with LSB, look for non-erased byte + for (i = j = 1; i <= 4; i++) + { + if (((*tmp) & NVOCMP_ERASEDBYTE) != NVOCMP_ERASEDBYTE) + { + // Last non-erased byte so far + j = i; + } + (*tmp) >>= 8; + } + +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + + return (ofs + j); +} +#else +static uint16_t NVOCMP_findOffset(uint8_t pg, uint16_t ofs) +{ + uint8_t i, j; + uint32_t tmp = 0; + + // Find first non-erased 4-byte location + while (ofs >= sizeof(tmp)) + { + ofs -= sizeof(tmp); + NVOCMP_read(pg, ofs, (uint8_t *) &tmp, sizeof(tmp)); + if (tmp != NVOCMP_ERASEDWORD) + { + break; + } + } + + // Starting with LSB, look for non-erased byte + for (i = j = 1; i <= 4; i++) + { + if ((tmp & NVOCMP_ERASEDBYTE) != NVOCMP_ERASEDBYTE) + { + // Last non-erased byte so far + j = i; + } + tmp >>= 8; + } + + return (ofs + j); +} +#endif + +/****************************************************************************** + * @fn NVOCMP_findItem + * + * @brief Find a valid item from designated page and offset + * + * @param pNvHandle - pointer to NV handle + * @param pg - Valid NV page + * @param ofs - Offset in NV page from where to start search + * @param pHdr - pointer to item header + * @param flag - specifies type of search + * @param pInfo - pointer to item info + * + * @return When >0, offset to the item header for found item + * When <=0, -number of items searched when item not found + * + */ +#if NVOCMP_FASTITEM +static int8_t NVOCMP_findItem(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, uint16_t ofs, NVOCMP_itemHdr_t * pHdr, int8_t flag, + NVOCMP_itemInfo_t * pInfo) +{ + bool found = false; + uint8_t p; + uint16_t items = 0; + uint16_t nvSearched = 0; +#ifdef NVOCMP_GPRAM + uint32_t vm; + uint8_t * pTBuffer = RAM_BUFFER_ADDRESS; +#else + uint8_t * pTBuffer = (uint8_t *) tBuffer; +#endif + uint32_t cid = NVOCMP_CMPRID(pHdr->sysid, pHdr->itemid, pHdr->subid); + +#ifdef NVOCMP_GPRAM + NVOCMP_disableCache(&vm); +#endif + + for (p = pg; nvSearched < NVOCMP_NVSIZE; p = NVOCMP_DECPAGE(p), ofs = pNvHandle->pageInfo[p].offset) + { + nvSearched++; +#if (NVOCMP_NVPAGES != NVOCMP_NVONEP) + if (p == pNvHandle->tailPage) + { + continue; + } +#endif + NVOCMP_read(pg, 0, (uint8_t *) pTBuffer, FLASH_PAGE_SIZE); + + while (ofs >= (NVOCMP_PGDATAOFS + NVOCMP_ITEMHDRLEN)) + { + NVOCMP_itemHdr_t iHdr; + + // Align to start of item header + ofs -= NVOCMP_ITEMHDRLEN; + + // Read and decompress item header + NVOCMP_readHeader(p, ofs, &iHdr, true); + + if ((iHdr.stats & NVOCMP_ACTIVEIDBIT) && !(iHdr.stats & NVOCMP_VALIDIDBIT)) + { + uint32_t sysid = pHdr->sysid; + uint32_t itemid = pHdr->itemid; + + switch (flag & NVOCMP_FINDLMASK) + { + case NVOCMP_FINDANY: + found = true; + break; + case NVOCMP_FINDSTRICT: + // Return first cid match + if (cid == iHdr.cmpid) + { + found = true; + } + break; + case NVOCMP_FINDSYSID: + // return first sysid match + if (sysid == iHdr.sysid) + { + found = true; + } + break; + case NVOCMP_FINDITMID: + // return first sysid AND itemid match + if (sysid == iHdr.sysid && itemid == iHdr.itemid) + { + found = true; + } + break; + default: + // Should not get here + NVOCMP_EXCEPTION(p, NVINTF_BADPARAM); + NVOCMP_ASSERT(false, "Unhandled case in findItem().") +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + return (NVINTF_BADPARAM); + } + // Item found - return offset of item header + if (found) + { + if ((pInfo) && ((flag & NVOCMP_FINDHMASK) == NVOCMP_FINDCONTENT)) + { + if (!NVOCMP_readItem(&iHdr, 0, pInfo->rlength, pInfo->rBuf, false)) + { + if (!memcmp((uint8_t *) pInfo->rBuf + pInfo->coff, pInfo->cBuf, pInfo->clength)) + { + memcpy(pHdr, &iHdr, sizeof(NVOCMP_itemHdr_t)); +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + return (NVINTF_SUCCESS); + } + } + found = false; + } + else + { + memcpy(pHdr, &iHdr, sizeof(NVOCMP_itemHdr_t)); +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + return (NVINTF_SUCCESS); + } + } + } + // Try to jump to next item + if (iHdr.stats & NVOCMP_FOLLOWBIT) + { + // Appears to be an item there, check bounds + if (iHdr.len < ofs) + { + // Adjust offset for next try + ofs -= iHdr.len; + } + else + { + // Length is corrupt, mark item invalid and compact + NVOCMP_ALERT(false, "Item length corrupted. Deleting item.") + NVOCMP_setItemInactive(pNvHandle, p, ofs); +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + NVOCMP_compactPage(pNvHandle, 0); + p = NVOCMP_INCPAGE(pNvHandle->actPage); + ofs = 0; + nvSearched = 0; + } + } + else + { + // Something is corrupted, compact to fix + NVOCMP_ALERT(false, + "No item following current item, " + "compaction needed.") +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + NVOCMP_compactPage(pNvHandle, 0); + p = NVOCMP_INCPAGE(pNvHandle->actPage); + ofs = 0; + nvSearched = 0; + } + // Running count of items searched + items += 1; + } + } +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + // Item not found (negate number of items searched) + // or nth not found, return last found + pHdr->hofs = 0; + return (NVINTF_NOTFOUND); +} +#else +static int8_t NVOCMP_findItem(NVOCMP_nvHandle_t * pNvHandle, uint8_t pg, uint16_t ofs, NVOCMP_itemHdr_t * pHdr, int8_t flag, + NVOCMP_itemInfo_t * pInfo) +{ + bool found = false; + uint8_t p = pg; + uint16_t items = 0; + uint32_t cid = NVOCMP_CMPRID(pHdr->sysid, pHdr->itemid, pHdr->subid); + +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) + uint16_t nvSearched = 0; + for (p = pg; nvSearched < NVOCMP_NVSIZE; p = NVOCMP_DECPAGE(p), ofs = pNvHandle->pageInfo[p].offset) + { + nvSearched++; + if (p == pNvHandle->tailPage) + { + continue; + } +#endif + while (ofs >= (NVOCMP_PGDATAOFS + NVOCMP_ITEMHDRLEN)) + { + NVOCMP_itemHdr_t iHdr; + + // Align to start of item header + ofs -= NVOCMP_ITEMHDRLEN; + + // Read and decompress item header + NVOCMP_readHeader(p, ofs, &iHdr, false); + + if ((iHdr.stats & NVOCMP_ACTIVEIDBIT) && !(iHdr.stats & NVOCMP_VALIDIDBIT)) + { + uint32_t sysid = pHdr->sysid; + uint32_t itemid = pHdr->itemid; + + switch (flag & NVOCMP_FINDLMASK) + { + case NVOCMP_FINDANY: + found = true; + break; + case NVOCMP_FINDSTRICT: + // Return first cid match + if (cid == iHdr.cmpid) + { + found = true; + } + break; + case NVOCMP_FINDSYSID: + // return first sysid match + if (sysid == iHdr.sysid) + { + found = true; + } + break; + case NVOCMP_FINDITMID: + // return first sysid AND itemid match + if (sysid == iHdr.sysid && itemid == iHdr.itemid) + { + found = true; + } + break; + default: + // Should not get here + NVOCMP_EXCEPTION(p, NVINTF_BADPARAM); + NVOCMP_ASSERT(false, "Unhandled case in findItem().") + return (NVINTF_BADPARAM); + } + // Item found - return offset of item header + if (found) + { + if ((pInfo) && ((flag & NVOCMP_FINDHMASK) == NVOCMP_FINDCONTENT)) + { + if (!NVOCMP_readItem(&iHdr, 0, pInfo->rlength, pInfo->rBuf, false)) + { + if (!memcmp((uint8_t *) pInfo->rBuf + pInfo->coff, pInfo->cBuf, pInfo->clength)) + { + memcpy(pHdr, &iHdr, sizeof(NVOCMP_itemHdr_t)); + return (NVINTF_SUCCESS); + } + } + found = false; + } + else + { + memcpy(pHdr, &iHdr, sizeof(NVOCMP_itemHdr_t)); + return (NVINTF_SUCCESS); + } + } + } + // Try to jump to next item + if (iHdr.stats & NVOCMP_FOLLOWBIT) + { + // Appears to be an item there, check bounds + if (iHdr.len < ofs) + { + // Adjust offset for next try + ofs -= iHdr.len; + } + else + { + // Length is corrupt, mark item invalid and compact + NVOCMP_ALERT(false, "Item length corrupted. Deleting item.") + NVOCMP_setItemInactive(pNvHandle, p, ofs); + NVOCMP_compactPage(pNvHandle, 0); +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) + p = NVOCMP_INCPAGE(pNvHandle->actPage); + ofs = 0; + nvSearched = 0; +#else + p = pNvHandle->actPage; + ofs = pNvHandle->actOffset; +#endif + } + } + else + { + // Something is corrupted, compact to fix + NVOCMP_ALERT(false, + "No item following current item, " + "compaction needed.") + pNvHandle->forceCompact = 1; + NVOCMP_compactPage(pNvHandle, 0); +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) + p = NVOCMP_INCPAGE(pNvHandle->actPage); + ofs = 0; + nvSearched = 0; +#else + p = pNvHandle->actPage; + ofs = pNvHandle->actOffset; +#endif + } + // Running count of items searched + items += 1; + } +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) + } +#endif + // Item not found (negate number of items searched) + // or nth not found, return last found + pHdr->hofs = 0; + return (NVINTF_NOTFOUND); +} +#endif + +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) +/****************************************************************************** + * @fn NVOCMP_cleanPage + * + * @brief Clean the page that compaction is done with + * + * @param pNvHandle - pointer to NV handle + * + * @return Number of pages cleaned + */ +static uint8_t NVOCMP_cleanPage(NVOCMP_nvHandle_t * pNvHandle) +{ + uint8_t pg; + uint8_t pages = 0; + NVOCMP_pageHdr_t pageHdr; + NVOCMP_compactHdr_t startHdr; + NVOCMP_compactHdr_t endHdr; + + /* correct ofset */ + pg = pNvHandle->compactInfo.xDstPage; + NVOCMP_getCompactHdr(pg, XSRCSTARTHDR, &startHdr); + NVOCMP_getCompactHdr(pg, XSRCENDHDR, &endHdr); + for (pg = pNvHandle->compactInfo.xSrcSPage; pg != NVOCMP_INCPAGE(pNvHandle->compactInfo.xSrcEPage); pg = NVOCMP_INCPAGE(pg)) + { + if (pg == endHdr.page) + { + pNvHandle->pageInfo[pg].offset = endHdr.pageOffset; + } + else + { + pNvHandle->pageInfo[pg].offset = NVOCMP_PGDATAOFS; + } + } + /* end of correction */ + + for (pg = pNvHandle->compactInfo.xSrcSPage; pg != NVOCMP_INCPAGE(pNvHandle->compactInfo.xSrcEPage); pg = NVOCMP_INCPAGE(pg)) + { + if (pNvHandle->pageInfo[pg].offset == NVOCMP_PGDATAOFS) + { + pages++; + NVOCMP_failW = NVOCMP_erase(pNvHandle, pg); + } + else + { + NVOCMP_failW = NVOCMP_write(pg, (THISPAGEHDR + 1) * NVOCMP_COMPACTHDRLEN, (uint8_t *) &pNvHandle->pageInfo[pg].offset, + sizeof(pNvHandle->pageInfo[pg].offset)); + NVOCMP_read(pg, NVOCMP_PGHDROFS, (uint8_t *) &pageHdr, NVOCMP_PGHDRLEN); + if (pageHdr.state == NVOCMP_PGACT) + { + NVOCMP_changePageState(pNvHandle, pg, NVOCMP_PGFULL); + } + else + { + // this should not hit + if (pageHdr.state == NVOCMP_PGXDST) + { + NVOCMP_ASSERT1(0); + } + } + } + } + return (pages); +} +#endif + +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) +/****************************************************************************** + * @fn NVOCMP_compactPage + * + * @brief Compact specified page by copying active items to other page + * + * Compaction occurs under three circumstances: (1) 'maintenance' + * activity which is triggered by a user call to compactNvApi(), + * (2) 'update' activity where an NV page is packed to make room + * for an item being written. The 'update' mode is performed by + * writing the item after the rest of the page has been compacted, + * and (3) when corruption is detected in the NV page. The compaction + * operation will move all active&valid items to the other page. + * + * @param pNvHandle - pointer to NV handle + * @param nBytes - size of item to write if any + * + * @return Number of available bytes on compacted page, -1 if error + */ +static int16_t NVOCMP_compactPage(NVOCMP_nvHandle_t * pNvHandle, uint16_t nBytes) +{ + uint8_t pg; + uint8_t mode; + uint8_t srcPg; + uint8_t dstPg; + uint16_t needBytes; + uint16_t compactPages; + uint16_t cleanPages; + uint16_t skipPages = 0; + bool foundRoom = false; + NVOCMP_compactStatus_t status; + NVOCMP_pageHdr_t pageHdr; + uint8_t allActivePages = 0; + uint8_t err = NVINTF_SUCCESS; + + // Check voltage if possible + NVOCMP_FLASHACCESS(err) + if (err) + { + return (0); + } + + srcPg = pNvHandle->headPage; + dstPg = pNvHandle->tailPage; + compactPages = NVOCMP_NVSIZE - 1; + if (nBytes) + { + pNvHandle->compactInfo.xSrcPages = 1; + } + else + { + pNvHandle->compactInfo.xSrcPages = NVOCMP_NVSIZE - 1; + } + + // mark page mode + for (pg = 0; pg < NVOCMP_NVSIZE; pg++) + { + if (pg != dstPg) + { + NVOCMP_read(pg, NVOCMP_PGHDROFS, (uint8_t *) &pageHdr, NVOCMP_PGHDRLEN); + if (pageHdr.allActive) + { + allActivePages++; + } + if (pageHdr.state == NVOCMP_PGACT || pageHdr.state == NVOCMP_PGFULL) + { + mode = NVOCMP_PGCSRC; + NVOCMP_writeByte(pg, NVOCMP_COMPMODEOFS, mode); + pNvHandle->pageInfo[pg].mode = mode; + } + } + } + + if ((allActivePages == NVOCMP_NVSIZE - 1) && !pNvHandle->forceCompact) + { + return (0); + } + + while (compactPages) + { + if (pNvHandle->compactInfo.xSrcPages == 0) + { + pNvHandle->compactInfo.xSrcPages = 1; + } + // Get page header + NVOCMP_read(srcPg, NVOCMP_PGHDROFS, (uint8_t *) &pageHdr, NVOCMP_PGHDRLEN); +#if NVOCMP_FASTCP + if (nBytes && pageHdr.allActive) + { + srcPg = NVOCMP_INCPAGE(srcPg); + pNvHandle->compactInfo.xDstOffset = FLASH_PAGE_SIZE; + pNvHandle->compactInfo.xSrcSPage = srcPg; + pNvHandle->compactInfo.xSrcPages--; + compactPages--; + skipPages++; + continue; + } +#endif + // Mark source page to be in PGXSRC state + if (pageHdr.state != NVOCMP_PGXSRC) + { + NVOCMP_changePageState(pNvHandle, srcPg, NVOCMP_PGXSRC); + } + // Get page header + NVOCMP_read(dstPg, NVOCMP_PGHDROFS, (uint8_t *) &pageHdr, NVOCMP_PGHDRLEN); + // Mark destination page to be in PGXDST state + if (pageHdr.state != NVOCMP_PGXDST) + { + NVOCMP_changePageState(pNvHandle, dstPg, NVOCMP_PGXDST); + } + + mode = NVOCMP_PGCDST; + NVOCMP_writeByte(dstPg, NVOCMP_COMPMODEOFS, mode); + pNvHandle->pageInfo[dstPg].mode = mode; + + pNvHandle->compactInfo.xDstPage = dstPg; + pNvHandle->compactInfo.xDstOffset = FLASH_PAGE_SIZE; + pNvHandle->compactInfo.xSrcSPage = srcPg; + pNvHandle->compactInfo.xSrcSOffset = pNvHandle->pageInfo[srcPg].offset; + pNvHandle->compactInfo.xSrcEPage = NVOCMP_NULLPAGE; + pNvHandle->compactInfo.xSrcEOffset = 0; + status = NVOCMP_compact(pNvHandle); + + if (status == NVOCMP_COMPACT_FAILURE) + { +#ifdef NVOCMP_RECOVER_FROM_COMPACT_FAILURE + uint8_t p; + for (p = 0; p < NVOCMP_NVSIZE; p++) + { + NVOCMP_failW |= NVOCMP_erase(pNvHandle, p); + if ((p != 0) && (p != NVOCMP_NVSIZE - 1)) + { + NVOCMP_changePageState(pNvHandle, p, NVOCMP_PGRDY); + } + } + pNvHandle->actPage = 0; + pNvHandle->actOffset = pNvHandle->pageInfo[0].offset; + pNvHandle->headPage = 0; + pNvHandle->tailPage = NVOCMP_NVSIZE - 1; + NVOCMP_changePageState(pNvHandle, NVOCMP_NVSIZE - 1, NVOCMP_PGXDST); + NVOCMP_changePageState(pNvHandle, 0, NVOCMP_PGACT); + + pNvHandle->forceCompact = 0; +#endif + return (0); + } + + needBytes = nBytes ? nBytes : 16; + + if (nBytes) + { + if (FLASH_PAGE_SIZE - pNvHandle->compactInfo.xDstOffset >= needBytes) + { + foundRoom = true; + } + } + // change XDST page state + if (FLASH_PAGE_SIZE - pNvHandle->compactInfo.xDstOffset >= needBytes) + { + NVOCMP_changePageState(pNvHandle, dstPg, NVOCMP_PGACT); + } + else + { + NVOCMP_changePageState(pNvHandle, dstPg, NVOCMP_PGFULL); + } + // clean XSRC pages + cleanPages = NVOCMP_cleanPage(pNvHandle); + compactPages -= cleanPages; + pNvHandle->compactInfo.xSrcPages -= cleanPages; + + // mark XDST page as done + mode = NVOCMP_PGCDONE; + NVOCMP_writeByte(dstPg, NVOCMP_COMPMODEOFS, mode); + pNvHandle->pageInfo[dstPg].mode = mode; + + // move tail page and head page + pNvHandle->tailPage = NVOCMP_ADDPAGE(pNvHandle->tailPage, cleanPages + skipPages); + pNvHandle->headPage = NVOCMP_INCPAGE(pNvHandle->tailPage); + skipPages = 0; + // set next source page + if (pNvHandle->pageInfo[pNvHandle->compactInfo.xSrcEPage].offset == NVOCMP_PGDATAOFS) + { + srcPg = NVOCMP_INCPAGE(pNvHandle->compactInfo.xSrcEPage); + } + else + { + srcPg = pNvHandle->compactInfo.xSrcEPage; + } + + // set next destination page + dstPg = pNvHandle->tailPage; + if (nBytes && foundRoom) + { + break; + } + } + + pg = NVOCMP_findPage(NVOCMP_PGACT); + if (pg == NVOCMP_NULLPAGE) + { + pg = NVOCMP_findPage(NVOCMP_PGRDY); + if (pg == NVOCMP_NULLPAGE) + { + if (pNvHandle->pageInfo[pNvHandle->headPage].state == NVOCMP_PGNACT) + { + pg = pNvHandle->headPage; + NVOCMP_changePageState(pNvHandle, pg, NVOCMP_PGRDY); + } + else + { + pg = NVOCMP_DECPAGE(pNvHandle->tailPage); + } + } + } + + pNvHandle->actPage = pg; + pNvHandle->actOffset = pNvHandle->pageInfo[pNvHandle->actPage].offset; + NVOCMP_changePageState(pNvHandle, pNvHandle->tailPage, NVOCMP_PGXDST); + + pNvHandle->forceCompact = 0; + return (FLASH_PAGE_SIZE - pNvHandle->compactInfo.xDstOffset); +} +#else +/****************************************************************************** + * @fn NVOCMP_compactPage + * + * @brief Compact specified page by copying active items to other page + * + * Compaction occurs under three circumstances: (1) 'maintenance' + * activity which is triggered by a user call to compactNvApi(), + * (2) 'update' activity where an NV page is packed to make room + * for an item being written. The 'update' mode is performed by + * writing the item after the rest of the page has been compacted, + * and (3) when corruption is detected in the NV page. The compaction + * operation will move all active&valid items to the other page. + * + * @param pNvHandle - pointer to NV handle + * @param nBytes - size of item to write if any + * + * @return Number of available bytes on compacted page, -1 if error + */ +static int16_t NVOCMP_compactPage(NVOCMP_nvHandle_t * pNvHandle, uint16_t nBytes) +{ + uint8_t srcPg; + uint8_t dstPg; + uint16_t needBytes; + NVOCMP_compactStatus_t status; + NVOCMP_pageHdr_t pageHdr; + uint8_t err = NVINTF_SUCCESS; + + // Check voltage if possible + NVOCMP_FLASHACCESS(err) + if (err) + { + return (0); + } + +#if (NVOCMP_NVPAGES == NVOCMP_NVONEP) + srcPg = 0; + dstPg = 0; +#else + srcPg = pNvHandle->headPage; + dstPg = pNvHandle->tailPage; +#endif + pNvHandle->compactInfo.xSrcPages = 1; + + // mark page mode + NVOCMP_read(srcPg, NVOCMP_PGHDROFS, (uint8_t *) &pageHdr, NVOCMP_PGHDRLEN); + if ((NVOCMP_ALLACTIVE == pageHdr.allActive) && !pNvHandle->forceCompact) + { + return (0); + } + + NVOCMP_writeByte(srcPg, NVOCMP_COMPMODEOFS, NVOCMP_PGCSRC); + pNvHandle->pageInfo[srcPg].mode = NVOCMP_PGCSRC; + + // Mark source page to be in PGXSRC state + if (pageHdr.state != NVOCMP_PGXSRC) + { + NVOCMP_changePageState(pNvHandle, srcPg, NVOCMP_PGXSRC); + } +#if (NVOCMP_NVPAGES > NVOCMP_NVONEP) + // Get page header + NVOCMP_read(dstPg, NVOCMP_PGHDROFS, (uint8_t *) &pageHdr, NVOCMP_PGHDRLEN); + // Mark destination page to be in PGXDST state + if (pageHdr.state != NVOCMP_PGXDST) + { + NVOCMP_changePageState(pNvHandle, dstPg, NVOCMP_PGXDST); + } + + NVOCMP_writeByte(dstPg, NVOCMP_COMPMODEOFS, NVOCMP_PGCDST); + pNvHandle->pageInfo[dstPg].mode = NVOCMP_PGCDST; +#endif + + pNvHandle->compactInfo.xSrcSOffset = pNvHandle->pageInfo[srcPg].offset; + status = NVOCMP_compact(pNvHandle); + + if (status == NVOCMP_COMPACT_FAILURE) + { +#ifdef NVOCMP_RECOVER_FROM_COMPACT_FAILURE + uint8_t p; + for (p = 0; p < NVOCMP_NVSIZE; p++) + { + NVOCMP_failW |= NVOCMP_erase(pNvHandle, p); + if ((p != 0) && (p != NVOCMP_NVSIZE - 1)) + { + NVOCMP_changePageState(pNvHandle, p, NVOCMP_PGRDY); + } + } + pNvHandle->actPage = 0; + pNvHandle->actOffset = pNvHandle->pageInfo[0].offset; + pNvHandle->headPage = 0; + pNvHandle->tailPage = NVOCMP_NVSIZE - 1; + NVOCMP_changePageState(pNvHandle, NVOCMP_NVSIZE - 1, NVOCMP_PGXDST); + NVOCMP_changePageState(pNvHandle, 0, NVOCMP_PGACT); + + pNvHandle->forceCompact = 0; +#endif + return (0); + } + + needBytes = nBytes ? nBytes : 16; + + // change XDST page state + if (FLASH_PAGE_SIZE - pNvHandle->compactInfo.xDstOffset >= needBytes) + { + NVOCMP_changePageState(pNvHandle, dstPg, NVOCMP_PGACT); + } + else + { + NVOCMP_changePageState(pNvHandle, dstPg, NVOCMP_PGFULL); + } + +#if (NVOCMP_NVPAGES > NVOCMP_NVONEP) + // clean XSRC pages + NVOCMP_failW = NVOCMP_erase(pNvHandle, srcPg); +#endif + + // mark XDST page as done + NVOCMP_writeByte(dstPg, NVOCMP_COMPMODEOFS, NVOCMP_PGCDONE); + pNvHandle->pageInfo[dstPg].mode = NVOCMP_PGCDONE; + + // move tail page and head page + pNvHandle->tailPage = srcPg; + pNvHandle->headPage = dstPg; + pNvHandle->actPage = dstPg; + pNvHandle->actOffset = pNvHandle->pageInfo[dstPg].offset; +#if (NVOCMP_NVPAGES > NVOCMP_NVONEP) + NVOCMP_changePageState(pNvHandle, srcPg, NVOCMP_PGXDST); +#endif + + pNvHandle->forceCompact = 0; + return (FLASH_PAGE_SIZE - pNvHandle->actOffset); +} +#endif + +/****************************************************************************** + * @fn NVOCMP_findSignature + * + * @brief Local function to scan page to get page information + * + * @param pg - page to search + * @param pSrcOff - source off to start search from + * + * @return NVINTF_SUCCESS or specific failure code + */ +static bool NVOCMP_findSignature(uint8_t pg, uint16_t * pSrcOff) +{ + uint16_t i; + uint16_t rdLen; + uint8_t readBuffer[NVOCMP_XFERBLKMAX]; + uint16_t srcOff = *pSrcOff; + uint16_t endOff = NVOCMP_PGDATAOFS + NVOCMP_ITEMHDRLEN - 1; + + while (srcOff > endOff) + { + rdLen = (srcOff - NVOCMP_XFERBLKMAX > endOff) ? NVOCMP_XFERBLKMAX : srcOff - endOff; + srcOff -= rdLen; + NVOCMP_read(pg, srcOff, readBuffer, rdLen); + for (i = rdLen; i > 0; i--) + { + if (readBuffer[i - 1] == NVOCMP_SIGNATURE) + { + // Found possible header, resume normal operation + NVOCMP_ALERT(false, "Found possible signature.") + srcOff += i; // srcOff should point to one byte ahead + *pSrcOff = srcOff; + return (true); + } + } + } + return (false); +} + +#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP) +/****************************************************************************** + * @fn NVOCMP_compact + * + * @brief Local function to compact NV + * + * @param pNvHandle - pointer to NV handler + * + * @return NVINTF_SUCCESS or specific failure code + */ +static NVOCMP_compactStatus_t NVOCMP_compact(NVOCMP_nvHandle_t * pNvHandle) +{ + bool needScan = false; + bool needSkip = false; + bool dstFull = false; + uint16_t dstOff; + uint16_t endOff; + uint16_t srcOff; + uint16_t crcOff; + uint8_t srcStartPg; + uint8_t srcEndPg; + uint8_t dstPg; + uint8_t srcPg; + uint32_t aItem = 0; +#ifndef NVOCMP_RAM_OPTIMIZATION +#ifdef NVOCMP_GPRAM + uint32_t vm; + uint8_t * pTBuffer = RAM_BUFFER_ADDRESS; +#else + uint8_t * pTBuffer = (uint8_t *) tBuffer; +#endif +#endif + + NVOCMP_compactStatus_t status = NVOCMP_COMPACT_SUCCESS; + +#ifndef NVOCMP_GPRAM + memset(tBuffer, 0, sizeof(tBuffer)); +#endif + // Reset Flash erase/write fail indicator + NVOCMP_failW = NVINTF_SUCCESS; + srcStartPg = pNvHandle->compactInfo.xSrcSPage; + srcEndPg = NVOCMP_ADDPAGE(srcStartPg, pNvHandle->compactInfo.xSrcPages - 1); + + // Stop looking when we get to this offset + endOff = NVOCMP_PGDATAOFS + NVOCMP_ITEMHDRLEN - 1; + + srcPg = srcStartPg; + srcOff = pNvHandle->pageInfo[srcPg].offset; + dstPg = pNvHandle->compactInfo.xDstPage; + dstOff = pNvHandle->pageInfo[dstPg].offset; + + NVOCMP_ALERT(false, "Compaction triggered.") + +#ifdef NVOCMP_GPRAM + NVOCMP_disableCache(&vm); +#endif + while (srcPg != dstPg) + { + if (dstFull) + { + if (aItem) + { + pNvHandle->pageInfo[srcPg].offset = srcOff; + } + break; + } + + if (srcOff <= endOff) + { + if (aItem) + { + pNvHandle->pageInfo[srcPg].offset = srcOff; + } + if (srcPg == srcEndPg) + { + break; + } + else + { + srcPg = NVOCMP_INCPAGE(srcPg); + srcOff = pNvHandle->pageInfo[srcPg].offset; + aItem = 0; + continue; + } + } + + if (NVOCMP_failW == NVINTF_SUCCESS) + { + NVOCMP_itemHdr_t srcHdr; + uint16_t dataLen; + uint16_t itemSize; + + needScan = false; + needSkip = false; + + // Read and decompress item header + NVOCMP_readHeader(srcPg, srcOff - NVOCMP_ITEMHDRLEN, &srcHdr, false); + dataLen = srcHdr.len; + itemSize = NVOCMP_ITEMHDRLEN + dataLen; + crcOff = srcOff - NVOCMP_ITEMHDRLEN - dataLen; + + // Check if length is safe + if (srcOff < (dataLen + NVOCMP_PGDATAOFS)) + { + NVOCMP_ALERT(false, "Item header corrupted: Data length too long") + needScan = true; + srcOff--; + } + else if (NVOCMP_SIGNATURE != srcHdr.sig) + { + NVOCMP_ALERT(false, "Item header corrupted: Invalid signature") + needScan = true; + srcOff--; + } + else if (NVOCMP_verifyCRC(crcOff, dataLen, srcHdr.crc8, srcPg, false)) + { + // Invalid CRC, corruption + NVOCMP_ALERT(false, "Item CRC incorrect!") + needScan = true; + srcOff--; + } + else if (!(srcHdr.stats & NVOCMP_VALIDIDBIT) && // Item is valid + (srcHdr.stats & NVOCMP_ACTIVEIDBIT)) // Item is active + { + // Valid CRC, item is active + srcOff -= NVOCMP_ITEMHDRLEN; + } + else + { + // Valid CRC but item is inactive + srcOff -= NVOCMP_ITEMHDRLEN; + needSkip = true; + } + + if (needScan) + { + // Detected a problem, find next header (scan for signature) + NVOCMP_ALERT(false, "Attempting to find signature...") + bool foundSig = NVOCMP_findSignature(srcPg, &srcOff); + if (!foundSig) + { +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + // If we get here and foundSig is false, we never found another + // item in the page, break the loop so that any valid items + // that were collected up to this point get written to the + // destination page. + NVOCMP_ALERT(foundSig, "Attempt to find signature failed.") + break; + } + } + else + { + if (!needSkip) + { + if (dstOff + itemSize > FLASH_PAGE_SIZE) + { + // cannot fit one page temp buffer and revert srcOff change + srcOff += NVOCMP_ITEMHDRLEN; + dstFull = true; + continue; + } + else + { + // Get block of bytes from source page +#ifndef NVOCMP_RAM_OPTIMIZATION +#if NVOCMP_COMPR + NVOCMP_read(srcPg, crcOff, (uint8_t *) (pTBuffer + dstOff), itemSize); +#else + NVOCMP_read(srcPg, crcOff, (uint8_t *) (pTBuffer + FLASH_PAGE_SIZE - dstOff - itemSize), itemSize); +#endif +#else + NVOCMP_copyItem(srcPg, dstPg, crcOff, dstOff, itemSize); +#endif + dstOff += itemSize; + aItem++; + if (dstOff == FLASH_PAGE_SIZE) + { + dstFull = true; + } + } + } + NVOCMP_ALERT(srcOff > dataLen, "Offset overflow: srcOff") + srcOff -= dataLen; + } + } + else + { +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + // Failure during item xfer makes next findItem() unreliable + NVOCMP_ASSERT(false, "COMPACTION FAILURE") + return (NVOCMP_COMPACT_FAILURE); + } + } // end of while + + if (NVOCMP_failW != NVINTF_SUCCESS) + { +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + // Something bad happened when trying to compact the page + NVOCMP_ASSERT(false, "COMPACTION FAILURE") + return (NVOCMP_COMPACT_FAILURE); + } + + // Write block to destination page +#ifndef NVOCMP_RAM_OPTIMIZATION +#if NVOCMP_COMPR + uint16_t off = NVOCMP_PGDATAOFS; + uint16_t len = dstOff - NVOCMP_PGDATAOFS; + + NVOCMP_failW |= NVOCMP_write(dstPg, off, (uint8_t *) (pTBuffer + off), len); +#else + uint16_t off = NVOCMP_PGDATAOFS; + uint16_t doff = FLASH_PAGE_SIZE - dstOff; + uint16_t len = dstOff - NVOCMP_PGDATAOFS; + + NVOCMP_failW |= NVOCMP_write(dstPg, off, (uint8_t *) (pTBuffer + doff), len); +#endif +#endif + +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + + if (srcPg == dstPg) + { + srcPg = NVOCMP_DECPAGE(srcPg); + srcOff = pNvHandle->pageInfo[srcPg].offset; + } + pNvHandle->compactInfo.xDstOffset = dstOff; + pNvHandle->compactInfo.xSrcEOffset = srcOff; + + pNvHandle->compactInfo.xSrcEPage = srcPg; + pNvHandle->pageInfo[dstPg].offset = dstOff; + + NVOCMP_setCompactHdr(dstPg, pNvHandle->compactInfo.xSrcSPage, pNvHandle->compactInfo.xSrcSOffset, XSRCSTARTHDR); + NVOCMP_setCompactHdr(dstPg, pNvHandle->compactInfo.xSrcEPage, pNvHandle->compactInfo.xSrcEOffset, XSRCENDHDR); + + if (srcOff <= endOff) + { + status |= NVOCMP_COMPACT_SRCDONE; + } + if (dstOff >= FLASH_PAGE_SIZE) + { + status |= NVOCMP_COMPACT_DSTDONE; + } + + return (status); +} +#else +/****************************************************************************** + * @fn NVOCMP_compact + * + * @brief Local function to compact NV + * + * @param pNvHandle - pointer to NV handler + * + * @return NVINTF_SUCCESS or specific failure code + */ +static NVOCMP_compactStatus_t NVOCMP_compact(NVOCMP_nvHandle_t * pNvHandle) +{ + bool needScan = false; + bool needSkip = false; + uint16_t dstOff; + uint16_t endOff; + uint16_t srcOff; + uint16_t crcOff; + uint8_t dstPg; + uint8_t srcPg; + uint32_t aItem = 0; +#ifndef NVOCMP_RAM_OPTIMIZATION +#ifdef NVOCMP_GPRAM + uint32_t vm; + uint8_t * pTBuffer = RAM_BUFFER_ADDRESS; +#else + uint8_t * pTBuffer = (uint8_t *) tBuffer; +#endif +#endif + +#ifndef NVOCMP_GPRAM + memset(tBuffer, 0, sizeof(tBuffer)); +#endif + // Reset Flash erase/write fail indicator + NVOCMP_failW = NVINTF_SUCCESS; + + // Stop looking when we get to this offset + endOff = NVOCMP_PGDATAOFS + NVOCMP_ITEMHDRLEN - 1; + +#if (NVOCMP_NVPAGES == NVOCMP_NVONEP) + srcPg = 0; + srcOff = pNvHandle->pageInfo[0].offset; + dstPg = 0; + dstOff = NVOCMP_PGDATAOFS; +#else + srcPg = pNvHandle->headPage; + srcOff = pNvHandle->pageInfo[srcPg].offset; + dstPg = pNvHandle->tailPage; + dstOff = pNvHandle->pageInfo[dstPg].offset; +#endif + + NVOCMP_ALERT(false, "Compaction triggered.") + +#ifdef NVOCMP_GPRAM + NVOCMP_disableCache(&vm); +#endif + while (srcOff > endOff) + { + if (NVOCMP_failW == NVINTF_SUCCESS) + { + NVOCMP_itemHdr_t srcHdr; + uint16_t dataLen; + uint16_t itemSize; + + needScan = false; + needSkip = false; + + // Read and decompress item header + NVOCMP_readHeader(srcPg, srcOff - NVOCMP_ITEMHDRLEN, &srcHdr, false); + dataLen = srcHdr.len; + itemSize = NVOCMP_ITEMHDRLEN + dataLen; + crcOff = srcOff - NVOCMP_ITEMHDRLEN - dataLen; + + // Check if length is safe + if (srcOff < (dataLen + NVOCMP_PGDATAOFS)) + { + NVOCMP_ALERT(false, "Item header corrupted: Data length too long") + needScan = true; + srcOff--; + } + else if (NVOCMP_SIGNATURE != srcHdr.sig) + { + NVOCMP_ALERT(false, "Item header corrupted: Invalid signature") + needScan = true; + srcOff--; + } + else if (NVOCMP_verifyCRC(crcOff, dataLen, srcHdr.crc8, srcPg, false)) + { + // Invalid CRC, corruption + NVOCMP_ALERT(false, "Item CRC incorrect!") + needScan = true; + srcOff--; + } + else if (!(srcHdr.stats & NVOCMP_VALIDIDBIT) && // Item is valid + (srcHdr.stats & NVOCMP_ACTIVEIDBIT)) // Item is active + { + // Valid CRC, item is active + srcOff -= NVOCMP_ITEMHDRLEN; + } + else + { + // Valid CRC but item is inactive + srcOff -= NVOCMP_ITEMHDRLEN; + needSkip = true; + } + + if (needScan) + { + // Detected a problem, find next header (scan for signature) + NVOCMP_ALERT(false, "Attempting to find signature...") + bool foundSig = NVOCMP_findSignature(srcPg, &srcOff); + if (!foundSig) + { + // If we get here and foundSig is false, we never found another + // item in the page, break the loop so that any valid items + // that were collected up to this point get written to the + // destination page. + NVOCMP_ALERT(foundSig, "Attempt to find signature failed.") + break; + } + } + else + { + if (!needSkip) + { + // Get block of bytes from source page +#ifndef NVOCMP_RAM_OPTIMIZATION +#if NVOCMP_COMPR + NVOCMP_read(srcPg, crcOff, (uint8_t *) (pTBuffer + dstOff), itemSize); +#else + NVOCMP_read(srcPg, crcOff, (uint8_t *) (pTBuffer + FLASH_PAGE_SIZE - dstOff - itemSize), itemSize); +#endif +#else + NVOCMP_copyItem(srcPg, dstPg, crcOff, dstOff, itemSize); +#endif + dstOff += itemSize; + aItem++; + } + NVOCMP_ALERT(srcOff > dataLen, "Offset overflow: srcOff") + srcOff -= dataLen; + } + } + else + { +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + // Failure during item xfer makes next findItem() unreliable + NVOCMP_ASSERT(false, "COMPACTION FAILURE") + return (NVOCMP_COMPACT_FAILURE); + } + } // end of while + + if (NVOCMP_failW != NVINTF_SUCCESS) + { +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + // Something bad happened when trying to compact the page + NVOCMP_ASSERT(false, "COMPACTION FAILURE") + return (NVOCMP_COMPACT_FAILURE); + } + +#if (NVOCMP_NVPAGES == NVOCMP_NVONEP) + // Get XDST page ready + NVOCMP_failW = NVOCMP_erase(pNvHandle, dstPg); + NVOCMP_changePageState(pNvHandle, dstPg, NVOCMP_PGXDST); +#endif + + // Write block to destination page +#ifndef NVOCMP_RAM_OPTIMIZATION +#if NVOCMP_COMPR + uint16_t off = NVOCMP_PGDATAOFS; + uint16_t len = dstOff - NVOCMP_PGDATAOFS; + NVOCMP_failW |= NVOCMP_write(dstPg, off, (uint8_t *) (pTBuffer + off), len); +#else + uint16_t off = NVOCMP_PGDATAOFS; + uint16_t doff = FLASH_PAGE_SIZE - dstOff; + uint16_t len = dstOff - NVOCMP_PGDATAOFS; + NVOCMP_failW |= NVOCMP_write(dstPg, off, (uint8_t *) (pTBuffer + doff), len); +#endif +#endif + +#ifdef NVOCMP_GPRAM + NVOCMP_restoreCache(vm); +#endif + + pNvHandle->pageInfo[dstPg].offset = dstOff; + pNvHandle->compactInfo.xSrcEOffset = srcOff; + pNvHandle->compactInfo.xDstOffset = dstOff; + + NVOCMP_setCompactHdr(dstPg, pNvHandle->compactInfo.xSrcSPage, pNvHandle->compactInfo.xSrcSOffset, XSRCSTARTHDR); + NVOCMP_setCompactHdr(dstPg, pNvHandle->compactInfo.xSrcEPage, pNvHandle->compactInfo.xSrcEOffset, XSRCENDHDR); + + return (NVOCMP_COMPACT_SUCCESS); +} +#endif + +#if ((NVOCMP_NVPAGES > NVOCMP_NVONEP) && !defined(NVOCMP_MIGRATE_DISABLED)) || defined NVOCMP_RAM_OPTIMIZATION +/****************************************************************************** + * @fn NVOCMP_copyItem + * + * @brief Copy an NV item from active page to specified destination page + * + * @param srcPg - Source page + * @param dstPg - Destination page + * @param sOfs - Source page offset of original data in active page + * @param dOfs - Destination page offset to transferred copy of the item + * @param len - Length of data to copy + * + * @return none. + */ +static void NVOCMP_copyItem(uint8_t srcPg, uint8_t dstPg, uint16_t sOfs, uint16_t dOfs, uint16_t len) +{ + uint16_t num; +#ifndef NVOCMP_RAM_OPTIMIZATION + uint8_t tmp[NVOCMP_XFERBLKMAX]; +#else + uint8_t * tmp = (uint8_t *) tBuffer; +#endif + + // Copy over the data: Flash to RAM, then RAM to Flash + while (len > 0 && !NVOCMP_failW) + { + // Number of bytes to transfer in this block +#ifndef NVOCMP_RAM_OPTIMIZATION + num = (len < NVOCMP_XFERBLKMAX) ? len : NVOCMP_XFERBLKMAX; +#else + num = (len < NVOCMP_RAM_BUFFER_SIZE) ? len : NVOCMP_RAM_BUFFER_SIZE; +#endif + + // Get block of bytes from source page + NVOCMP_read(srcPg, sOfs, (uint8_t *) &tmp[0], num); + + // Write block to destination page + NVOCMP_failW = NVOCMP_write(dstPg, dOfs, (uint8_t *) &tmp[0], num); + + dOfs += num; + sOfs += num; + len -= num; + } +} +#endif +/****************************************************************************** + * @fn NVOCMP_readByte + * + * @brief Read one byte from Flash memory + * + * @param pg - NV Flash page + * @param ofs - Offset into the page + * + * @return byte read from flash memory + */ +static uint8_t NVOCMP_readByte(uint8_t pg, uint16_t ofs) +{ + uint8_t byteVal; + NVOCMP_read(pg, ofs, &byteVal, NVOCMP_ONEBYTE); + + return (byteVal); +} + +/****************************************************************************** + * @fn NVOCMP_writeByte + * + * @brief Write one byte to Flash and read back to verify + * + * @param pg - NV Flash page + * @param ofs - offset into the page + * @param bwv - byte to write & verify + * + * @return none ('failF' or 'failW' will be set if write fails) + */ +static void NVOCMP_writeByte(uint8_t pg, uint16_t ofs, uint8_t bwv) +{ + NVOCMP_failW = NVOCMP_write(pg, ofs, &bwv, 1); +} + +/****************************************************************************** + * @fn NVOCMP_doNVCRC + * + * @brief Computes the CRC8 on the NV buffer indicated + * CRC code external, API in crc.h + * + * @param pg - Flash page to check + * @param ofs - Flash page offset to lowest address item byte + * @param len - Item data length + * @param crc - value to start with, should be NULL if new calculation + * @param flag - fast flag (not used if NVOCMP_RAM_OPTIMIZATION is defined) + * + * @return crc byte + */ +static uint8_t NVOCMP_doNVCRC(uint8_t pg, uint16_t ofs, uint16_t len, uint8_t crc, bool flag) +{ + uint16_t rdLen = 0; +#ifndef NVOCMP_RAM_OPTIMIZATION +#ifdef NVOCMP_GPRAM + uint8_t * pTBuffer = RAM_BUFFER_ADDRESS; +#else + uint8_t * pTBuffer = (uint8_t *) tBuffer; +#endif +#endif + uint8_t tmp[NVOCMP_XFERBLKMAX]; + crc_t newCRC = (crc_t) crc; + + // Read flash and compute CRC in blocks + while (len > 0) + { + rdLen = (len < NVOCMP_XFERBLKMAX ? len : NVOCMP_XFERBLKMAX); +#ifndef NVOCMP_RAM_OPTIMIZATION + if (flag) + { + memcpy((uint8_t *) tmp, (uint8_t *) (pTBuffer + ofs), rdLen); + } + else + { +#endif + NVOCMP_read(pg, ofs, tmp, rdLen); +#ifndef NVOCMP_RAM_OPTIMIZATION + } +#endif + newCRC = crc_update(newCRC, tmp, rdLen); + len -= rdLen; + ofs += rdLen; + } + + return (newCRC); +} + +/****************************************************************************** + * @fn NVOCMP_doRAMCRC + * + * @brief Calculates CRC8 given a buffer and length + * CRC code external, API in crc.h + * + * @param input - pointer to data buffer + * @param len - length of data in buffer + * @param crc - value to start with, should be NULL if new calculation + * + * @return CRC8 byte + */ +static uint8_t NVOCMP_doRAMCRC(uint8_t * input, uint16_t len, uint8_t crc) +{ + crc_t newCRC = crc_update((crc_t) crc, input, len); + + return ((uint8_t) newCRC); +} + +/****************************************************************************** + * @fn NVOCMP_verifyCRC + * + * @brief Helper function to validate item crc from NV + * + * @param iOfs - offset to item data + * @param len - length of item data + * @param crc - crc to compare against + * @param pg - page to work on + * @param flag - fast flag (not used if NVOCMP_RAM_OPTIMIZATION is defined) + * + * @return status byte + */ +static uint8_t NVOCMP_verifyCRC(uint16_t iOfs, uint16_t len, uint8_t crc, uint8_t pg, bool flag) +{ + uint8_t newCRC; + uint16_t crcLen = len + NVOCMP_HDRCRCINC - 1; +#if NVOCMP_HDRLE + uint8_t finalByte = (len >> 6) & 0x3F; +#else + uint8_t finalByte = (len & 0x3F) << 2; +#endif + // CRC calculations stop at the length field of header + // So the last byte must be done separately + newCRC = NVOCMP_doNVCRC(pg, iOfs, crcLen, 0, flag); + newCRC = NVOCMP_doRAMCRC(&finalByte, sizeof(finalByte), newCRC); + NVOCMP_ALERT(newCRC == crc, "Invalid CRC detected.") +#ifdef NVOCMP_STATS + if (newCRC != crc) + { + NVOCMP_badCRCCount++; + } +#endif // NVOCMP_STATS + return (newCRC == crc ? NVINTF_SUCCESS : NVINTF_CORRUPT); +} + +#ifdef ENABLE_SANITY_CHECK +/****************************************************************************** + * @fn NVOCMP_sanityCheckApi + * + * @brief Global function to perform a sanity check on the active + * partition to report if corruption has been detected. + * + * @param none + * + * @return 0: No failure found. + * Non-zero: failure, each bit representing a particular error + * as indicated in NV driver status codes defined in nvintf.h. + */ +static uint32_t NVOCMP_sanityCheckApi(void) +{ + NVOCMP_nvHandle_t * pNvHandle = &NVOCMP_nvHandle; + bool needScan = false; + bool needSkip = false; + uint16_t dstOff; + uint16_t endOff; + uint16_t srcOff; + uint16_t crcOff; + uint8_t dstPg; + uint8_t srcPg; + uint32_t ret = NVINTF_SUCCESS; + uint32_t aItem = 0; + + // Reset Flash erase/write fail indicator + NVOCMP_failW = NVINTF_SUCCESS; + + // Stop looking when we get to this offset + endOff = NVOCMP_PGDATAOFS + NVOCMP_ITEMHDRLEN - 1; + +#if (NVOCMP_NVPAGES == NVOCMP_NVONEP) + srcPg = 0; + srcOff = pNvHandle->pageInfo[0].offset; + dstPg = 0; + dstOff = NVOCMP_PGDATAOFS; +#else + srcPg = pNvHandle->headPage; + srcOff = pNvHandle->pageInfo[srcPg].offset; + dstPg = pNvHandle->tailPage; + dstOff = pNvHandle->pageInfo[dstPg].offset; +#endif + + NVOCMP_ALERT(false, "Sanity Check") + + while (srcOff > endOff) + { + if (NVOCMP_failW == NVINTF_SUCCESS) + { + NVOCMP_itemHdr_t srcHdr; + uint16_t dataLen; + uint16_t itemSize; + + needScan = false; + needSkip = false; + + // Read and decompress item header + NVOCMP_readHeader(srcPg, srcOff - NVOCMP_ITEMHDRLEN, &srcHdr, false); + dataLen = srcHdr.len; + itemSize = NVOCMP_ITEMHDRLEN + dataLen; + crcOff = srcOff - NVOCMP_ITEMHDRLEN - dataLen; + + // Check if length is safe + if (srcOff < (dataLen + NVOCMP_PGDATAOFS)) + { + NVOCMP_ALERT(false, "Item header corrupted: Data length too long") + ret |= (1 << NVINTF_BADLENGTH); + needScan = true; + srcOff--; + } + else if (NVOCMP_SIGNATURE != srcHdr.sig) + { + NVOCMP_ALERT(false, "Item header corrupted: Invalid signature") + ret |= (1 << NVINTF_NO_SIG); + needScan = true; + srcOff--; + } + else if (NVOCMP_verifyCRC(crcOff, dataLen, srcHdr.crc8, srcPg, false)) + { + // Invalid CRC, corruption + NVOCMP_ALERT(false, "Item CRC incorrect!") + ret |= (1 << NVINTF_CORRUPT); + needScan = true; + srcOff--; + } + else if (!(srcHdr.stats & NVOCMP_VALIDIDBIT) && // Item is valid + (srcHdr.stats & NVOCMP_ACTIVEIDBIT)) // Item is active + { + // Valid CRC, item is active + srcOff -= NVOCMP_ITEMHDRLEN; + } + else + { + // Valid CRC but item is inactive + srcOff -= NVOCMP_ITEMHDRLEN; + needSkip = true; + } + + if (needScan) + { + // Detected a problem, find next header (scan for signature) + NVOCMP_ALERT(false, "Attempting to find signature...") + bool foundSig = NVOCMP_findSignature(srcPg, &srcOff); + if (!foundSig) + { + // If we get here and foundSig is false, we never found another + // item in the page, break the loop and report that corruption + // has been detected + NVOCMP_ALERT(foundSig, "Attempt to find signature failed.") + ret |= (1 << NVINTF_NO_SIG); + break; + } + } + else + { + if (!needSkip) + { + dstOff += itemSize; + aItem++; + } + NVOCMP_ALERT(srcOff > dataLen, "Offset overflow: srcOff") + srcOff -= dataLen; + } + } + else + { + // Failure during item xfer makes next findItem() unreliable + NVOCMP_ASSERT(false, "SANITY CHECK FAILURE") + ret |= (1 << NVINTF_FAILURE); + } + } // end of while + + if (NVOCMP_failW != NVINTF_SUCCESS) + { + // Something bad happened when scanning the page + NVOCMP_ASSERT(false, "SANITY CHECK FAILURE") + ret |= (1 << NVINTF_FAILURE); + } + + return (ret); +} +#endif + +//***************************************************************************** diff --git a/third_party/openthread/ot-ti b/third_party/openthread/ot-ti index 6f30243676724e..e7fbbcc60c25d1 160000 --- a/third_party/openthread/ot-ti +++ b/third_party/openthread/ot-ti @@ -1 +1 @@ -Subproject commit 6f30243676724ef1472d20098e00eb20b3f20679 +Subproject commit e7fbbcc60c25d1dec3ed4d02cff9acd866091ce7 diff --git a/third_party/ti_simplelink_sdk/mcuboot/flash_map_backend.h b/third_party/ti_simplelink_sdk/mcuboot/flash_map_backend.h index de84f13558d573..e6c567591dc59b 100644 --- a/third_party/ti_simplelink_sdk/mcuboot/flash_map_backend.h +++ b/third_party/ti_simplelink_sdk/mcuboot/flash_map_backend.h @@ -77,7 +77,7 @@ #define BOOT_SECONDARY_2_BASE_ADDRESS (BOOT_SECONDARY_1_BASE_ADDRESS + BOOT_SECONDARY_1_SIZE) #define BOOT_SECONDARY_2_SIZE BOOT_SLOT_2_SIZE #else -#define BOOT_SLOT_1_SIZE 0x000F6000 +#define BOOT_SLOT_1_SIZE 0x000F2000 /* Internal Flash locations */ #define BOOTLOADER_BASE_ADDRESS 0x00000000 diff --git a/third_party/ti_simplelink_sdk/mcuboot/mcuboot_config/mcuboot_config.h b/third_party/ti_simplelink_sdk/mcuboot/mcuboot_config/mcuboot_config.h index 1977bb7af88f4d..cac6f807abd0b6 100644 --- a/third_party/ti_simplelink_sdk/mcuboot/mcuboot_config/mcuboot_config.h +++ b/third_party/ti_simplelink_sdk/mcuboot/mcuboot_config/mcuboot_config.h @@ -27,7 +27,7 @@ #define MCUBOOT_DOWNGRADE_PREVENTION #define MCUBOOT_HAVE_LOGGING 1 #define MCUBOOT_IMAGE_NUMBER 1 -#define MCUBOOT_MAX_IMG_SECTORS 492 +#define MCUBOOT_MAX_IMG_SECTORS 484 #define MCUBOOT_OVERWRITE_ONLY #define MCUBOOT_SIGN_EC256 #define MCUBOOT_USE_FLASH_AREA_GET_SECTORS diff --git a/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni b/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni index 94e7851bc60a35..3df24854297f49 100644 --- a/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni +++ b/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni @@ -176,7 +176,7 @@ template("ti_simplelink_executable") { "--align", "4", "--slot-size", - "0x000F6000", # must match the flash_map_backend definitions + "0x000F2000", # must match the flash_map_backend definitions "--version", matter_software_ver_str, "--pad-header", diff --git a/third_party/ti_simplelink_sdk/ti_simplelink_sdk.gni b/third_party/ti_simplelink_sdk/ti_simplelink_sdk.gni index af3e810d67e6bf..b3aae392cfb39d 100644 --- a/third_party/ti_simplelink_sdk/ti_simplelink_sdk.gni +++ b/third_party/ti_simplelink_sdk/ti_simplelink_sdk.gni @@ -347,8 +347,8 @@ template("ti_simplelink_sdk") { configs -= [ "${build_root}/config/compiler:std_default" ] configs += [ ":${sdk_target_name}_posix_config" ] sources = [ + "${chip_root}/src/platform/cc13xx_26xx/nvocmp.c", "${ti_simplelink_sdk_root}/source/ti/common/nv/crc.c", - "${ti_simplelink_sdk_root}/source/ti/common/nv/nvocmp.c", ] public_configs = [ ":${sdk_target_name}_config" ] @@ -398,7 +398,7 @@ template("ti_simplelink_sdk") { defines += [ "ONE_BLE_LIB_SIZE_OPTIMIZATION", - "NVOCMP_NVPAGES=5", + "NVOCMP_NVPAGES=12", "NVOCMP_NWSAMEITEM=1", "CC13X2P", "SYSCFG", From 1919112f5227471d74fa8f0f4df408b99e63c539 Mon Sep 17 00:00:00 2001 From: shripad621git <79364691+shripad621git@users.noreply.github.com> Date: Tue, 2 Jul 2024 02:36:13 +0530 Subject: [PATCH 03/10] [ESP32] Compilation fix when IPV4 is disabled. (#33085) * Compilation fix when IPV4 is disabled. * Addressed review comments and documented the IPv4 disabled change * Update docs/guides/esp32/config_options.md Co-authored-by: Shubham Patil * Update docs/guides/esp32/config_options.md Co-authored-by: Shubham Patil * Resolved the build failure for m5-stack ipv6 only test --------- Co-authored-by: Shubham Patil --- config/esp32/components/chip/CMakeLists.txt | 6 +++++- docs/guides/esp32/README.md | 1 + docs/guides/esp32/config_options.md | 13 +++++++++++++ examples/chef/chef.py | 4 ++++ examples/chef/esp32/sdkconfig.defaults | 3 +++ examples/chef/esp32/sdkconfig_rpc.defaults | 3 +++ examples/platform/esp32/Rpc.cpp | 2 ++ scripts/build/builders/esp32.py | 2 ++ ...32-m5stack-all-clusters-minimal-rpc-ipv6only.txt | 2 ++ src/platform/ESP32/BUILD.gn | 2 ++ src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp | 2 ++ 11 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 docs/guides/esp32/config_options.md diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt index 672cf849af1244..d0c1fc4463f442 100644 --- a/config/esp32/components/chip/CMakeLists.txt +++ b/config/esp32/components/chip/CMakeLists.txt @@ -118,7 +118,11 @@ chip_gn_arg_append("chip_config_network_layer_ble" "false") endif() if(CONFIG_DISABLE_IPV4) - chip_gn_arg_append("chip_inet_config_enable_ipv4" "false") + if(NOT CONFIG_LWIP_IPV4) + chip_gn_arg_append("chip_inet_config_enable_ipv4" "false") + else() + message(FATAL_ERROR "Please also disable config option CONFIG_LWIP_IPV4") + endif() endif() if(CONFIG_DISABLE_READ_CLIENT) diff --git a/docs/guides/esp32/README.md b/docs/guides/esp32/README.md index 443058a17b07aa..86cb3a94256257 100644 --- a/docs/guides/esp32/README.md +++ b/docs/guides/esp32/README.md @@ -19,3 +19,4 @@ example on ESP32 series of SoCs - [Generating and Using ESP Secure Cert Partition](secure_cert_partition.md) - [BLE Settings](ble_settings.md) - [Providers](providers.md) +- [Configuration Options](config_options.md) diff --git a/docs/guides/esp32/config_options.md b/docs/guides/esp32/config_options.md new file mode 100644 index 00000000000000..646e725daa9d1e --- /dev/null +++ b/docs/guides/esp32/config_options.md @@ -0,0 +1,13 @@ +# Configuration options + +This file lists down few config options to be configured through menuconfig for +specific scenarios. + +### Building with IPV4 Disabled + +Configure below options through `idf.py menuconfig` and build the app. + +``` +CONFIG_DISABLE_IPV4=y +CONFIG_LWIP_IPV4=n +``` diff --git a/examples/chef/chef.py b/examples/chef/chef.py index f681f3a059f4fc..c4b7aa8aca162b 100755 --- a/examples/chef/chef.py +++ b/examples/chef/chef.py @@ -706,9 +706,13 @@ def main() -> int: if sys.platform == "darwin": shell.run_cmd( "sed -i '' 's/#\\ CONFIG_DISABLE_IPV4\\ is\\ not\\ set/CONFIG_DISABLE_IPV4=y/g' sdkconfig ") + shell.run_cmd( + "sed -i '' 's/CONFIG_LWIP_IPV4=y/#\\ CONFIG_LWIP_IPV4\\ is\\ not\\ set/g' sdkconfig ") else: shell.run_cmd( "sed -i 's/#\\ CONFIG_DISABLE_IPV4\\ is\\ not\\ set/CONFIG_DISABLE_IPV4=y/g' sdkconfig ") + shell.run_cmd( + "sed -i 's/CONFIG_LWIP_IPV4=y/#\\ CONFIG_LWIP_IPV4\\ is\\ not\\ set/g' sdkconfig ") shell.run_cmd("idf.py build") shell.run_cmd("idf.py build flashing_script") diff --git a/examples/chef/esp32/sdkconfig.defaults b/examples/chef/esp32/sdkconfig.defaults index fc09afaa38a00a..ac78ca7aed36ac 100644 --- a/examples/chef/esp32/sdkconfig.defaults +++ b/examples/chef/esp32/sdkconfig.defaults @@ -39,6 +39,9 @@ CONFIG_LWIP_IPV6_AUTOCONFIG=y # disable IPV4 # CONFIG_DISABLE_IPV4 is not set +# lwip IPV4 config +CONFIG_LWIP_IPV4=y + # Use a custom partition table CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" diff --git a/examples/chef/esp32/sdkconfig_rpc.defaults b/examples/chef/esp32/sdkconfig_rpc.defaults index 1b9f9ddc30134f..9e2c1a59bd509f 100644 --- a/examples/chef/esp32/sdkconfig_rpc.defaults +++ b/examples/chef/esp32/sdkconfig_rpc.defaults @@ -36,6 +36,9 @@ CONFIG_LWIP_IPV6_AUTOCONFIG=y # disable IPV4 # CONFIG_DISABLE_IPV4 is not set +# lwip configuration +CONFIG_LWIP_IPV4=y + # Use a custom partition table CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" diff --git a/examples/platform/esp32/Rpc.cpp b/examples/platform/esp32/Rpc.cpp index a3b61830b5a46a..7c00267be89780 100644 --- a/examples/platform/esp32/Rpc.cpp +++ b/examples/platform/esp32/Rpc.cpp @@ -197,6 +197,7 @@ class Esp32WiFi final : public WiFi return pw::OkStatus(); } +#if CHIP_DEVICE_CONFIG_ENABLE_IPV4 pw::Status GetIP4Address(const pw_protobuf_Empty & request, chip_rpc_IP4Address & response) override { esp_netif_ip_info_t ip_info; @@ -204,6 +205,7 @@ class Esp32WiFi final : public WiFi snprintf(response.address, sizeof(response.address), IPSTR, IP2STR(&ip_info.ip)); return pw::OkStatus(); } +#endif pw::Status GetIP6Address(const pw_protobuf_Empty & request, chip_rpc_IP6Address & response) override { diff --git a/scripts/build/builders/esp32.py b/scripts/build/builders/esp32.py index 3528a5873050e4..018e20170b194b 100644 --- a/scripts/build/builders/esp32.py +++ b/scripts/build/builders/esp32.py @@ -197,6 +197,8 @@ def generate(self): if not self.enable_ipv4: self._Execute( ['bash', '-c', 'echo -e "\\nCONFIG_DISABLE_IPV4=y\\n" >>%s' % shlex.quote(defaults_out)]) + self._Execute( + ['bash', '-c', 'echo -e "\\nCONFIG_LWIP_IPV4=n\\n" >>%s' % shlex.quote(defaults_out)]) if self.enable_insights_trace: insights_flag = 'y' diff --git a/scripts/build/testdata/dry_run_esp32-m5stack-all-clusters-minimal-rpc-ipv6only.txt b/scripts/build/testdata/dry_run_esp32-m5stack-all-clusters-minimal-rpc-ipv6only.txt index 708d254115dc33..7d6977d6fc05cc 100644 --- a/scripts/build/testdata/dry_run_esp32-m5stack-all-clusters-minimal-rpc-ipv6only.txt +++ b/scripts/build/testdata/dry_run_esp32-m5stack-all-clusters-minimal-rpc-ipv6only.txt @@ -10,6 +10,8 @@ rm -f examples/all-clusters-minimal-app/esp32/sdkconfig bash -c 'echo -e "\nCONFIG_DISABLE_IPV4=y\n" >>{out}/esp32-m5stack-all-clusters-minimal-rpc-ipv6only/sdkconfig.defaults' +bash -c 'echo -e "\nCONFIG_LWIP_IPV4=n\n" >>{out}/esp32-m5stack-all-clusters-minimal-rpc-ipv6only/sdkconfig.defaults' + bash -c 'echo -e "\nCONFIG_ESP_INSIGHTS_ENABLED=n\nCONFIG_ENABLE_ESP_INSIGHTS_TRACE=n\n" >>{out}/esp32-m5stack-all-clusters-minimal-rpc-ipv6only/sdkconfig.defaults' bash -c 'source $IDF_PATH/export.sh; source scripts/activate.sh; diff --git a/src/platform/ESP32/BUILD.gn b/src/platform/ESP32/BUILD.gn index 2d5d9449b2243e..e835896fb59092 100644 --- a/src/platform/ESP32/BUILD.gn +++ b/src/platform/ESP32/BUILD.gn @@ -14,6 +14,7 @@ import("//build_overrides/chip.gni") +import("${chip_root}/src/inet/inet.gni") import("${chip_root}/src/platform/device.gni") assert(chip_device_platform == "esp32") @@ -36,6 +37,7 @@ declare_args() { defines = [ "CHIP_CONFIG_SOFTWARE_VERSION_NUMBER=${chip_config_software_version_number}", + "CHIP_DEVICE_CONFIG_ENABLE_IPV4=${chip_inet_config_enable_ipv4}", ] static_library("ESP32") { diff --git a/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp b/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp index bbeaf6cdbc7169..380edfd3e7adc9 100644 --- a/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp +++ b/src/platform/ESP32/ConnectivityManagerImpl_WiFi.cpp @@ -999,6 +999,7 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState(void) // If the station interface has been assigned an IPv4 address, and has // an IPv4 gateway, then presume that the device has IPv4 Internet // connectivity. +#if CHIP_DEVICE_CONFIG_ENABLE_IPV4 if (!ip4_addr_isany_val(*netif_ip4_addr(netif)) && !ip4_addr_isany_val(*netif_ip4_gw(netif))) { haveIPv4Conn = true; @@ -1013,6 +1014,7 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState(void) IPAddress::FromString(addrStr, addr); } } +#endif // Search among the IPv6 addresses assigned to the interface for a Global Unicast // address (2000::/3) that is in the valid state. If such an address is found... From 247f05d7b20b54d0ca50b5eca8d7f3662aafb6a8 Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Tue, 2 Jul 2024 22:23:36 +1200 Subject: [PATCH 04/10] Revert "Add test logic to Matter Casting Automation test script for commissioner-generated-passcode flow. (#34079)" (#34151) This reverts commit 176896a83c415d1de1a59467d770c074cc9d81d7. "Test TV Casting Example / Linux Test" has been failing in master and all PRs since this landed. See https://github.com/project-chip/connectedhomeip/actions/workflows/examples-linux-tv-casting-app.yaml --- .../examples-linux-tv-casting-app.yaml | 12 +- .../tests/linux/tv_casting_test_sequences.py | 118 +----------------- scripts/tests/run_tv_casting_test.py | 30 ++--- 3 files changed, 13 insertions(+), 147 deletions(-) diff --git a/.github/workflows/examples-linux-tv-casting-app.yaml b/.github/workflows/examples-linux-tv-casting-app.yaml index 2797712bffa816..ca6d1b6ea20e5c 100644 --- a/.github/workflows/examples-linux-tv-casting-app.yaml +++ b/.github/workflows/examples-linux-tv-casting-app.yaml @@ -63,22 +63,12 @@ jobs: ./scripts/run_in_build_env.sh \ "scripts/examples/gn_build_example.sh examples/tv-casting-app/linux/ out/tv-casting-app chip_casting_simplified=true" - - name: - Test casting from Linux tv-casting-app to Linux tv-app - - Commissionee Generated Passcode + - name: Test casting from Linux tv-casting-app to Linux tv-app run: | ./scripts/run_in_build_env.sh \ "python3 ./scripts/tests/run_tv_casting_test.py" timeout-minutes: 2 # Comment this out to debug if GitHub Action times out. - - name: - Test casting from Linux tv-casting-app to Linux tv-app - - Commissioner Generated Passcode - run: | - ./scripts/run_in_build_env.sh \ - "python3 ./scripts/tests/run_tv_casting_test.py --commissioner-generated-passcode=True" - timeout-minutes: 2 # Comment this out to debug if GitHub Action times out. - - name: Uploading Size Reports uses: ./.github/actions/upload-size-reports if: ${{ !env.ACT }} diff --git a/scripts/tests/linux/tv_casting_test_sequences.py b/scripts/tests/linux/tv_casting_test_sequences.py index 4ac5623e511aa6..3ed249ae28532f 100644 --- a/scripts/tests/linux/tv_casting_test_sequences.py +++ b/scripts/tests/linux/tv_casting_test_sequences.py @@ -67,13 +67,9 @@ # Values that identify the Linux tv-app and are noted in the 'Device Configuration' in the Linux tv-app output # as well as under the 'Discovered Commissioner' details in the Linux tv-casting-app output. -VENDOR_ID = 0xFFF1 # 0xFFF1 = 65521; Spec 7.20.2.1 MEI code: test vendor IDs are 0xFFF1 to 0xFFF4 -PRODUCT_ID = 0x8001 # 0x8001 = 32769 = Test product id -DEVICE_TYPE_CASTING_VIDEO_PLAYER = 0x23 # 0x23 = 35 = Device type library 10.3: Casting Video Player - -# 0x457 = 1111 = Target Content Application Vendor ID for the commissioner generated passcode flow -COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID = 0x457 -COMMISSIONER_GENERATED_PASSCODE = '0x00BC_614E' # 0x00BC_614E = 12345678 = Default commissioner generated passcode +VENDOR_ID = 0xFFF1 # Spec 7.20.2.1 MEI code: test vendor IDs are 0xFFF1 to 0xFFF4 +PRODUCT_ID = 0x8001 # Test product id +DEVICE_TYPE_CASTING_VIDEO_PLAYER = 0x23 # Device type library 10.3: Casting Video Player # Value to verify the subscription state against in the Linux tv-casting-app output. ATTRIBUTE_CURRENT_PLAYBACK_STATE = 0x0000_0000 # Application Cluster Spec 6.10.6 Attribute ID: Current State of Playback @@ -98,7 +94,7 @@ Step(app=App.TV_CASTING_APP, output_msg=['Discovered CastingPlayer #0', f'Product ID: {PRODUCT_ID}', f'Vendor ID: {VENDOR_ID}', f'Device Type: {DEVICE_TYPE_CASTING_VIDEO_PLAYER}', 'Supports Commissioner Generated Passcode: true']), - # Send `cast request {valid_discovered_castingplayer_number}\n` command to the tv-casting-app subprocess. + # Send `cast request {valid_discovered_commissioner_number}\n` command to the tv-casting-app subprocess. Step(app=App.TV_CASTING_APP, input_cmd='cast request 0\n'), # Validate that the tv-casting-app begins the commissioning process. @@ -116,7 +112,7 @@ # Validate that we received the instructions on the tv-app output for sending the `controller ux ok` command. Step(app=App.TV_APP, output_msg=['Via Shell Enter: controller ux ok|cancel']), - # Send `controller ux ok\n` command to the tv-app subprocess. + # Send `controller ux ok` command to the tv-app subprocess. Step(app=App.TV_APP, input_cmd='controller ux ok\n'), # Validate that pairing succeeded between the tv-casting-app and the tv-app. @@ -144,110 +140,6 @@ # Signal to stop the tv-casting-app as we finished validation. Step(app=App.TV_CASTING_APP, input_cmd=STOP_APP), - # Signal to stop the tv-app as we finished validation. - Step(app=App.TV_APP, input_cmd=STOP_APP) - ] - ), - Sequence( - name='commissioner_generated_passcode_test', - steps=[ - # Signal to start the tv-app. - Step(app=App.TV_APP, input_cmd=START_APP), - - # Validate that the tv-app is up and running. - Step(app=App.TV_APP, timeout_sec=APP_MAX_START_WAIT_SEC, output_msg=['Started commissioner']), - - # Signal to start the tv-casting-app. - Step(app=App.TV_CASTING_APP, input_cmd=START_APP), - - # Validate that the server is properly initialized in the tv-casting-app output. - Step(app=App.TV_CASTING_APP, timeout_sec=APP_MAX_START_WAIT_SEC, output_msg=['Server initialization complete']), - - # Validate that there is a valid discovered casting player with {PRODUCT_ID}, {VENDOR_ID}, {DEVICE_TYPE_CASTING_VIDEO_PLAYER}, and the - # `Commissioner Generated Passcode` flag is set to true in the tv-casting-app output. - Step(app=App.TV_CASTING_APP, output_msg=['Discovered CastingPlayer #0', f'Product ID: {PRODUCT_ID}', f'Vendor ID: {VENDOR_ID}', - f'Device Type: {DEVICE_TYPE_CASTING_VIDEO_PLAYER}', 'Supports Commissioner Generated Passcode: true']), - - # Send `cast request {valid_discovered_castingplayer_number} commissioner-generated-passcode\n` command to the tv-casting-app subprocess. - Step(app=App.TV_CASTING_APP, input_cmd='cast request 0 commissioner-generated-passcode\n'), - - # Validate that the tv-casting-app begins the commissioning process. - Step(app=App.TV_CASTING_APP, output_msg=[ - 'CastingPlayer::VerifyOrEstablishConnection() calling OpenBasicCommissioningWindow()']), - - # Validate that the `IdentificationDeclaration` message sent from the tv-casting-app to the tv-app will contain the following entries: - # mCommissionerPasscode: true -> This flag instructs the commissioner to use the commissioner-generated-passcode flow for commissioning. - # mCommissionerPasscodeReady: false -> This flag indicates that the commissionee has not obtained the commissioner passcode from the user and - # thus is not ready for commissioning. - # Vendor ID: {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID} -> The initial VENDOR_ID of the casting player will be overridden to {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID}. - # Otherwise we will enter the commissionee-generated-passcode flow. - Step(app=App.TV_CASTING_APP, output_msg=['IdentificationDeclarationOptions::LogDetail()', 'IdentificationDeclarationOptions::mCommissionerPasscode: true', - 'IdentificationDeclarationOptions::mCommissionerPasscodeReady: false', 'IdentificationDeclarationOptions::TargetAppInfos list:', f'TargetAppInfo 1, Vendor ID: {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID}']), - - # Validate that we received the cast request from the tv-casting-app on the tv-app output. - Step(app=App.TV_APP, - output_msg=['------PROMPT USER: Test TV casting app is requesting permission to cast to this TV, approve?']), - - # Validate that we received the instructions on the tv-app output for sending the `controller ux ok` command. - Step(app=App.TV_APP, output_msg=['Via Shell Enter: controller ux ok|cancel']), - - # Send `controller ux ok` command to the tv-app subprocess. - Step(app=App.TV_APP, input_cmd='controller ux ok\n'), - - # Validate that the tv-app sent a message to the tv-casting-app indicating that the tv-app is now displaying the passcode to the user. - Step(app=App.TV_APP, output_msg=['Commissioner Declaration Start', - 'commissioner passcode: true', 'Commissioner Declaration End']), - - # Validate that we received the cast request with the casting passcode on the tv-app output. - Step(app=App.TV_APP, output_msg=[ - f'------PROMPT USER: Test TV casting app is requesting permission to cast to this TV. Casting passcode: [{COMMISSIONER_GENERATED_PASSCODE}].']), - - # Validate that the tv-casting-app received the message from the tv-app indicating that the tv-app is now displaying the passcode to the user. - Step(app=App.TV_CASTING_APP, output_msg=['Commissioner Declaration Start', - 'commissioner passcode: true', 'Commissioner Declaration End']), - - # Validate that the user is prompted to input passcode from the tv-app on the tv-casting-app output. - Step(app=App.TV_CASTING_APP, output_msg=['Awaiting user input', 'Input the Commissioner-Generated passcode displayed on the CastingPlayer UX.', - f'cast setcommissionerpasscode {int(COMMISSIONER_GENERATED_PASSCODE, 16)}', 'Awaiting user input']), - - # Send `cast setcommissionerpasscode {COMMISSIONER_GENERATED_PASSCODE}\n` to the tv-casting-app subprocess. - Step(app=App.TV_CASTING_APP, input_cmd=f'cast setcommissionerpasscode {int(COMMISSIONER_GENERATED_PASSCODE, 16)}\n'), - - # Validate the commissioner passcode that the user entered on the tv-casting-app output. - Step(app=App.TV_CASTING_APP, output_msg=[ - f'CommandHandler() setcommissionerpasscode user entered passcode: {int(COMMISSIONER_GENERATED_PASSCODE, 16)}']), - - # Validate that the `IdentificationDeclaration` message sent from the tv-casting-app to the tv-app will contain the following entries: - # mCommissionerPasscode: true -> This flag instructs the commissioner to use the commissioner-generated-passcode flow for commissioning. - # mCommissionerPasscodeReady: true -> This flag indicates that the commissionee has obtained the commissioner passcode from the user and - # thus is ready for commissioning. - # Vendor ID: {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID} -> The initial VENDOR_ID of the casting player will be overridden to {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID}. - # Otherwise we will enter the commissionee-generated-passcode flow. - Step(app=App.TV_CASTING_APP, output_msg=['IdentificationDeclarationOptions::LogDetail()', 'IdentificationDeclarationOptions::mCommissionerPasscode: true', - 'IdentificationDeclarationOptions::mCommissionerPasscodeReady: true', 'IdentificationDeclarationOptions::TargetAppInfos list:', f'TargetAppInfo 1, Vendor ID: {COMMISSIONER_GENERATED_PASSCODE_VENDOR_ID}']), - - # Validate that pairing succeeded between the tv-casting-app and the tv-app. - Step(app=App.TV_APP, output_msg=['Secure Pairing Success']), - - # Validate that the connection succeeded in the tv-casting-app output. - Step(app=App.TV_CASTING_APP, output_msg=['Successfully connected to CastingPlayer']), - - # Validate that commissioning succeeded in the tv-app output. - Step(app=App.TV_APP, output_msg=['------PROMPT USER: commissioning success']), - - # Validate that we are able to subscribe to the media playback cluster by reading the CurrentState value and that it matches {ATTRIBUTE_CURRENT_PLAYBACK_STATE}. - Step(app=App.TV_CASTING_APP, output_msg=[f'Read CurrentState value: {ATTRIBUTE_CURRENT_PLAYBACK_STATE}']), - - # Validate the LaunchURL in the tv-app output. - Step(app=App.TV_APP, - output_msg=['ContentLauncherManager::HandleLaunchUrl TEST CASE ContentURL=https://www.test.com/videoid DisplayString=Test video']), - - # Validate the LaunchURL in the tv-casting-app output. - Step(app=App.TV_CASTING_APP, output_msg=['LaunchURL Success with response.data: exampleData']), - - # Signal to stop the tv-casting-app as we finished validation. - Step(app=App.TV_CASTING_APP, input_cmd=STOP_APP), - # Signal to stop the tv-app as we finished validation. Step(app=App.TV_APP, input_cmd=STOP_APP) ] diff --git a/scripts/tests/run_tv_casting_test.py b/scripts/tests/run_tv_casting_test.py index c5cc34dd052eb3..13b003eed67e66 100644 --- a/scripts/tests/run_tv_casting_test.py +++ b/scripts/tests/run_tv_casting_test.py @@ -270,26 +270,12 @@ def run_test_sequence_steps( @click.command() @click.option('--tv-app-rel-path', type=str, default='out/tv-app/chip-tv-app', help='Path to the Linux tv-app executable.') @click.option('--tv-casting-app-rel-path', type=str, default='out/tv-casting-app/chip-tv-casting-app', help='Path to the Linux tv-casting-app executable.') -@click.option('--commissioner-generated-passcode', type=bool, default=False, help='Enable the commissioner generated passcode test flow.') -def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path, commissioner_generated_passcode): +def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path): """Test if the casting experience between the Linux tv-casting-app and the Linux tv-app continues to work. - By default, it uses the provided executable paths and the commissionee generated passcode flow as the test sequence. - - Example usages: - 1. Use default paths and test sequence: - python3 run_tv_casting_test.py - - 2. Use custom executable paths and default test sequence: - python3 run_tv_casting_test.py --tv-app-rel-path=path/to/tv-app --tv-casting-app-rel-path=path/to/tv-casting-app - - 3. Use default paths and a test sequence that is not the default test sequence (replace `test-sequence-name` with the actual name of the test sequence): - python3 run_tv_casting_test.py --test-sequence-name=True - - 4. Use custom executable paths and a test sequence that is not the default test sequence (replace `test-sequence-name` with the actual name of the test sequence): - python3 run_tv_casting_test.py --tv-app-rel-path=path/to/tv-app --tv-casting-app-rel-path=path/to/tv-casting-app --test-sequence-name=True - - Note: In order to enable a new test sequence, we also need to define a @click.option() entry for the test sequence. + Default paths for the executables are provided but can be overridden via command line arguments. + For example: python3 run_tv_casting_test.py --tv-app-rel-path=path/to/tv-app + --tv-casting-app-rel-path=path/to/tv-casting-app """ # Store the log files to a temporary directory. @@ -302,17 +288,15 @@ def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path, commissioner_gener # Get all the test sequences. test_sequences = Sequence.get_test_sequences() - # Get the test sequence that we are interested in validating. - test_sequence_name = 'commissionee_generated_passcode_test' - if commissioner_generated_passcode: - test_sequence_name = 'commissioner_generated_passcode_test' - test_sequence = Sequence.get_test_sequence_by_name(test_sequences, test_sequence_name) + # Get the test sequence of interest. + test_sequence = Sequence.get_test_sequence_by_name(test_sequences, 'commissionee_generated_passcode_test') if not test_sequence: logging.error('No test sequence found by the test sequence name provided.') handle_casting_failure(None, []) # At this point, we have retrieved the test sequence of interest. + test_sequence_name = test_sequence.name test_sequence_steps = test_sequence.steps # Configure command options to disable stdout buffering during tests. From 102faca744c28a1382fb02d16eb413edfc46ff33 Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Wed, 3 Jul 2024 01:02:58 +1200 Subject: [PATCH 05/10] ReadClient: Truncate data version list during encoding if necessary (#34111) * ReadClient: Truncate data version list during encoding if necessary The existing code made the assumption that if a list of versions was able to fit into the request packet when generating the first subscribe request, then any resubscribe containing data versions for the same clusters would also fit. However the data version numbers themselves can be updated when we receive reports, and this can cause the list to no longer fit the request packet, leaving us in a state where every resubscribe attempt would fail. Note that this change means even an initial subscribe request with a data version list that is too long will no longer fail; ReadClient will simply truncate the list as needed in all cases. * Apply comment suggestions from code review Co-authored-by: Boris Zbarsky * Treat CHIP_ERROR_BUFFER_TOO_SMALL the same * Switch data_model tests to pw_unit_test * Add WillSendMessage to loopback delegate and make source addresses more plausible * Add test for ReadClient data version truncation * Make the linter happy --------- Co-authored-by: Boris Zbarsky --- src/app/ReadClient.cpp | 49 +++++++---- src/app/ReadClient.h | 5 ++ src/controller/tests/data_model/BUILD.gn | 1 + .../tests/data_model/TestCommands.cpp | 3 +- src/controller/tests/data_model/TestRead.cpp | 84 ++++++++++++++++++- src/controller/tests/data_model/TestWrite.cpp | 3 +- src/messaging/tests/MessagingContext.h | 2 +- src/transport/raw/tests/NetworkTestHelpers.h | 23 ++++- 8 files changed, 151 insertions(+), 19 deletions(-) diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 78b0a56fdd7c26..470c875fbaac30 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -423,33 +423,54 @@ CHIP_ERROR ReadClient::BuildDataVersionFilterList(DataVersionFilterIBs::Builder continue; } - DataVersionFilterIB::Builder & filterIB = aDataVersionFilterIBsBuilder.CreateDataVersionFilter(); - ReturnErrorOnFailure(aDataVersionFilterIBsBuilder.GetError()); - ClusterPathIB::Builder & path = filterIB.CreatePath(); - ReturnErrorOnFailure(filterIB.GetError()); - ReturnErrorOnFailure(path.Endpoint(filter.mEndpointId).Cluster(filter.mClusterId).EndOfClusterPathIB()); - VerifyOrReturnError(filter.mDataVersion.HasValue(), CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorOnFailure(filterIB.DataVersion(filter.mDataVersion.Value()).EndOfDataVersionFilterIB()); - aEncodedDataVersionList = true; + TLV::TLVWriter backup; + aDataVersionFilterIBsBuilder.Checkpoint(backup); + CHIP_ERROR err = EncodeDataVersionFilter(aDataVersionFilterIBsBuilder, filter); + if (err == CHIP_NO_ERROR) + { + aEncodedDataVersionList = true; + } + else if (err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL) + { + // Packet is full, ignore the rest of the list + aDataVersionFilterIBsBuilder.Rollback(backup); + return CHIP_NO_ERROR; + } + else + { + return err; + } } return CHIP_NO_ERROR; } +CHIP_ERROR ReadClient::EncodeDataVersionFilter(DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder, + DataVersionFilter const & aFilter) +{ + // Caller has checked aFilter.IsValidDataVersionFilter() + DataVersionFilterIB::Builder & filterIB = aDataVersionFilterIBsBuilder.CreateDataVersionFilter(); + ReturnErrorOnFailure(aDataVersionFilterIBsBuilder.GetError()); + ClusterPathIB::Builder & path = filterIB.CreatePath(); + ReturnErrorOnFailure(filterIB.GetError()); + ReturnErrorOnFailure(path.Endpoint(aFilter.mEndpointId).Cluster(aFilter.mClusterId).EndOfClusterPathIB()); + ReturnErrorOnFailure(filterIB.DataVersion(aFilter.mDataVersion.Value()).EndOfDataVersionFilterIB()); + return CHIP_NO_ERROR; +} + CHIP_ERROR ReadClient::GenerateDataVersionFilterList(DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder, const Span & aAttributePaths, const Span & aDataVersionFilters, bool & aEncodedDataVersionList) { - if (!aDataVersionFilters.empty()) + // Give the callback a chance first, otherwise use the list we have, if any. + ReturnErrorOnFailure( + mpCallback.OnUpdateDataVersionFilterList(aDataVersionFilterIBsBuilder, aAttributePaths, aEncodedDataVersionList)); + + if (!aEncodedDataVersionList) { ReturnErrorOnFailure(BuildDataVersionFilterList(aDataVersionFilterIBsBuilder, aAttributePaths, aDataVersionFilters, aEncodedDataVersionList)); } - else - { - ReturnErrorOnFailure( - mpCallback.OnUpdateDataVersionFilterList(aDataVersionFilterIBsBuilder, aAttributePaths, aEncodedDataVersionList)); - } return CHIP_NO_ERROR; } diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index 219a5be73f0b09..9bfb628b47e252 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -339,6 +339,9 @@ class ReadClient : public Messaging::ExchangeDelegate * This will send either a Read Request or a Subscribe Request depending on * the InteractionType this read client was initialized with. * + * If the params contain more data version filters than can fit in the request packet + * the list will be truncated as needed, i.e. filter inclusion is on a best effort basis. + * * @retval #others fail to send read request * @retval #CHIP_NO_ERROR On success. */ @@ -559,6 +562,8 @@ class ReadClient : public Messaging::ExchangeDelegate CHIP_ERROR BuildDataVersionFilterList(DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder, const Span & aAttributePaths, const Span & aDataVersionFilters, bool & aEncodedDataVersionList); + CHIP_ERROR EncodeDataVersionFilter(DataVersionFilterIBs::Builder & aDataVersionFilterIBsBuilder, + DataVersionFilter const & aFilter); CHIP_ERROR ReadICDOperatingModeFromAttributeDataIB(TLV::TLVReader && aReader, PeerType & aType); CHIP_ERROR ProcessAttributeReportIBs(TLV::TLVReader & aAttributeDataIBsReader); CHIP_ERROR ProcessEventReportIBs(TLV::TLVReader & aEventReportIBsReader); diff --git a/src/controller/tests/data_model/BUILD.gn b/src/controller/tests/data_model/BUILD.gn index 017980c4cd11f7..d8ce821ed837af 100644 --- a/src/controller/tests/data_model/BUILD.gn +++ b/src/controller/tests/data_model/BUILD.gn @@ -35,6 +35,7 @@ chip_test_suite("data_model") { "${chip_root}/src/app/tests:helpers", "${chip_root}/src/app/util/mock:mock_ember", "${chip_root}/src/controller", + "${chip_root}/src/lib/core:string-builder-adapters", "${chip_root}/src/messaging/tests:helpers", "${chip_root}/src/transport/raw/tests:helpers", ] diff --git a/src/controller/tests/data_model/TestCommands.cpp b/src/controller/tests/data_model/TestCommands.cpp index b6d39ae41978bc..11b71415ad6ec5 100644 --- a/src/controller/tests/data_model/TestCommands.cpp +++ b/src/controller/tests/data_model/TestCommands.cpp @@ -22,7 +22,8 @@ * */ -#include +#include +#include #include "app/data-model/NullObject.h" #include diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index a27eb61fcb2901..906ba82a213042 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -16,7 +16,8 @@ * limitations under the License. */ -#include +#include +#include #include "system/SystemClock.h" #include "transport/SecureSession.h" @@ -25,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -3093,6 +3095,86 @@ TEST_F(TestRead, TestReadHandler_MultipleSubscriptionsWithDataVersionFilter) EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); } +TEST_F(TestRead, TestReadHandler_DataVersionFiltersTruncated) +{ + struct : public chip::Test::LoopbackTransportDelegate + { + size_t requestSize = 0; + void WillSendMessage(const Transport::PeerAddress & peer, const System::PacketBufferHandle & message) override + { + // We only care about the messages we (Alice) send to Bob, not the responses. + // Assume the first message we see in an iteration is the request. + if (peer == mpContext->GetBobAddress() && requestSize == 0) + { + requestSize = message->TotalLength(); + } + } + } loopbackDelegate; + mpContext->GetLoopback().SetLoopbackTransportDelegate(&loopbackDelegate); + + // Note that on the server side, wildcard expansion does not actually work for kTestEndpointId due + // to lack of meta-data, but we don't care about the reports we get back in this test. + AttributePathParams wildcardPath(kTestEndpointId, kInvalidClusterId, kInvalidAttributeId); + constexpr size_t maxDataVersionFilterCount = 100; + DataVersionFilter dataVersionFilters[maxDataVersionFilterCount]; + ClusterId nextClusterId = 0; + for (auto & dv : dataVersionFilters) + { + dv.mEndpointId = wildcardPath.mEndpointId; + dv.mClusterId = nextClusterId++; + dv.mDataVersion = MakeOptional(0x01000000u); + } + + // Keep increasing the number of data version filters until we see truncation kick in. + size_t lastRequestSize; + for (size_t count = 1; count <= maxDataVersionFilterCount; count++) + { + lastRequestSize = loopbackDelegate.requestSize; + loopbackDelegate.requestSize = 0; // reset + + ReadPrepareParams read(mpContext->GetSessionAliceToBob()); + read.mpAttributePathParamsList = &wildcardPath; + read.mAttributePathParamsListSize = 1; + read.mpDataVersionFilterList = dataVersionFilters; + read.mDataVersionFilterListSize = count; + + struct : public ReadClient::Callback + { + CHIP_ERROR error = CHIP_NO_ERROR; + bool done = false; + void OnError(CHIP_ERROR aError) override { error = aError; } + void OnDone(ReadClient * apReadClient) override { done = true; }; + + } readCallback; + + ReadClient readClient(app::InteractionModelEngine::GetInstance(), &mpContext->GetExchangeManager(), readCallback, + ReadClient::InteractionType::Read); + + EXPECT_EQ(readClient.SendRequest(read), CHIP_NO_ERROR); + + mpContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return readCallback.done; }); + EXPECT_EQ(readCallback.error, CHIP_NO_ERROR); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + + EXPECT_NE(loopbackDelegate.requestSize, 0u); + EXPECT_GE(loopbackDelegate.requestSize, lastRequestSize); + if (loopbackDelegate.requestSize == lastRequestSize) + { + ChipLogProgress(DataManagement, "Data Version truncation detected after %llu elements", + static_cast(count - 1)); + // With the parameters used in this test and current encoding rules we can fit 68 data versions + // into a packet. If we're seeing substantially less then something is likely gone wrong. + EXPECT_GE(count, 60u); + ExitNow(); + } + } + ChipLogProgress(DataManagement, "Unable to detect Data Version truncation, maxDataVersionFilterCount too small?"); + ADD_FAILURE(); + +exit: + mpContext->GetLoopback().SetLoopbackTransportDelegate(nullptr); +} + TEST_F(TestRead, TestReadHandlerResourceExhaustion_MultipleReads) { auto sessionHandle = mpContext->GetSessionBobToAlice(); diff --git a/src/controller/tests/data_model/TestWrite.cpp b/src/controller/tests/data_model/TestWrite.cpp index e0f2c19480a1b0..da5505ccd613a1 100644 --- a/src/controller/tests/data_model/TestWrite.cpp +++ b/src/controller/tests/data_model/TestWrite.cpp @@ -16,7 +16,8 @@ * limitations under the License. */ -#include +#include +#include #include "app-common/zap-generated/ids/Clusters.h" #include diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index 51525f967d1475..f0e950a2cfc2a9 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -94,7 +94,7 @@ class MessagingContext : public PlatformMemoryUser MessagingContext() : mInitialized(false), mAliceAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT + 1)), - mBobAddress(Transport::PeerAddress::UDP(GetAddress(), CHIP_PORT)) + mBobAddress(LoopbackTransport::LoopbackPeer(mAliceAddress)) {} // TODO Replace VerifyOrDie with Pigweed assert after transition app/tests to Pigweed. // TODO Currently src/app/icd/server/tests is using MessagingConetext as dependency. diff --git a/src/transport/raw/tests/NetworkTestHelpers.h b/src/transport/raw/tests/NetworkTestHelpers.h index 49890406bc6afb..fca2b6b04cfd7c 100644 --- a/src/transport/raw/tests/NetworkTestHelpers.h +++ b/src/transport/raw/tests/NetworkTestHelpers.h @@ -64,6 +64,10 @@ class LoopbackTransportDelegate public: virtual ~LoopbackTransportDelegate() {} + // Called by the loopback transport when a message is requested to be sent. + // This is called even if the message is subsequently rejected or dropped. + virtual void WillSendMessage(const Transport::PeerAddress & peer, const System::PacketBufferHandle & message) {} + // Called by the loopback transport when it drops one of a configurable number of messages (mDroppedMessageCount) after a // configurable allowed number of messages (mNumMessagesToAllowBeforeDropping) virtual void OnMessageDropped() {} @@ -72,6 +76,18 @@ class LoopbackTransportDelegate class LoopbackTransport : public Transport::Base { public: + // In test scenarios using the loopback transport, we're only ever given + // the address we're sending to, but we don't have any information about + // what our local address is. Assume our fake addresses come in pairs of + // even and odd port numbers, so we can calculate one from the other by + // flipping the LSB of the port number. + static Transport::PeerAddress LoopbackPeer(const Transport::PeerAddress & address) + { + Transport::PeerAddress other(address); + other.SetPort(address.GetPort() ^ 1); + return other; + } + void InitLoopbackTransport(System::Layer * systemLayer) { Reset(); @@ -100,7 +116,7 @@ class LoopbackTransport : public Transport::Base { auto item = std::move(_this->mPendingMessageQueue.front()); _this->mPendingMessageQueue.pop(); - _this->HandleMessageReceived(item.mDestinationAddress, std::move(item.mPendingMessage)); + _this->HandleMessageReceived(LoopbackPeer(item.mDestinationAddress), std::move(item.mPendingMessage)); } } @@ -108,6 +124,11 @@ class LoopbackTransport : public Transport::Base CHIP_ERROR SendMessage(const Transport::PeerAddress & address, System::PacketBufferHandle && msgBuf) override { + if (mDelegate != nullptr) + { + mDelegate->WillSendMessage(address, msgBuf); + } + if (mNumMessagesToAllowBeforeError == 0) { ReturnErrorOnFailure(mMessageSendError); From a8fe0cf09e3a1b999895e98355e6e13bcf59fa43 Mon Sep 17 00:00:00 2001 From: Gatien Chapon <43855183+chapongatien@users.noreply.github.com> Date: Tue, 2 Jul 2024 16:33:33 +0200 Subject: [PATCH 06/10] [NXP] Fixing Matter over thread support on rw61x platform (#34074) * [NXP] Adding new GN file to reference openthread version from ot-nxp * [NXP][common] Replace Optional class with std::optional to fix BR build Signed-off-by: Gatien Chapon * [NXP] Updating ot-nxp submodule version to latest NXP release Signed-off-by: Gatien Chapon * [NXP][workflows] Adding thread and thread + wifi build checks Signed-off-by: Gatien Chapon * [NXP][rw61x] Updating workflow to allow to indicate to checkout all nxp submodules Signed-off-by: Gatien Chapon * [NXP][rw61x] Updating workflow to add --recursive submodule update option Signed-off-by: Gatien Chapon --------- Signed-off-by: Gatien Chapon --- .github/workflows/examples-rw61x.yaml | 9 ++++++++- examples/all-clusters-app/nxp/rt/rw61x/.gn | 3 +++ examples/laundry-washer-app/nxp/rt/rw61x/.gn | 3 +++ examples/platform/nxp/common/gn/args.gni | 16 ++++++++++++++++ examples/thermostat/nxp/rt/rw61x/.gn | 3 +++ scripts/build/builders/rw61x.py | 2 ++ src/platform/nxp/common/DnssdImpl.cpp | 4 ++-- third_party/openthread/ot-nxp | 2 +- 8 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 examples/platform/nxp/common/gn/args.gni diff --git a/.github/workflows/examples-rw61x.yaml b/.github/workflows/examples-rw61x.yaml index eed41f209ed61d..15c25699f72284 100644 --- a/.github/workflows/examples-rw61x.yaml +++ b/.github/workflows/examples-rw61x.yaml @@ -48,7 +48,8 @@ jobs: - name: Checkout submodules & Bootstrap uses: ./.github/actions/checkout-submodules-and-bootstrap with: - platform: rw61x + platform: nxp + extra-submodule-parameters: --recursive - name: Set up environment for size reports uses: ./.github/actions/setup-size-reports @@ -61,6 +62,8 @@ jobs: scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ --target rw61x-all-clusters-app-wifi \ + --target rw61x-all-clusters-app-thread \ + --target rw61x-all-clusters-app-thread-wifi \ build \ --copy-artifacts-to out/artifacts \ " @@ -70,6 +73,8 @@ jobs: scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ --target rw61x-thermostat-wifi \ + --target rw61x-thermostat-thread \ + --target rw61x-thermostat-thread-wifi \ build \ --copy-artifacts-to out/artifacts \ " @@ -79,6 +84,8 @@ jobs: scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ --target rw61x-laundry-washer-wifi \ + --target rw61x-laundry-washer-thread \ + --target rw61x-laundry-washer-thread-wifi \ build \ --copy-artifacts-to out/artifacts \ " diff --git a/examples/all-clusters-app/nxp/rt/rw61x/.gn b/examples/all-clusters-app/nxp/rt/rw61x/.gn index c0a26c2dc77832..cbbec24fe8c308 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/.gn +++ b/examples/all-clusters-app/nxp/rt/rw61x/.gn @@ -28,6 +28,9 @@ default_args = { import("//args.gni") + # Import common example GN args + import("${chip_root}/examples/platform/nxp/common/gn/args.gni") + # Import default platform configs import("${chip_root}/src/platform/nxp/rt/rw61x/args.gni") } diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/.gn b/examples/laundry-washer-app/nxp/rt/rw61x/.gn index c0a26c2dc77832..cbbec24fe8c308 100644 --- a/examples/laundry-washer-app/nxp/rt/rw61x/.gn +++ b/examples/laundry-washer-app/nxp/rt/rw61x/.gn @@ -28,6 +28,9 @@ default_args = { import("//args.gni") + # Import common example GN args + import("${chip_root}/examples/platform/nxp/common/gn/args.gni") + # Import default platform configs import("${chip_root}/src/platform/nxp/rt/rw61x/args.gni") } diff --git a/examples/platform/nxp/common/gn/args.gni b/examples/platform/nxp/common/gn/args.gni new file mode 100644 index 00000000000000..a730fe7ad65c90 --- /dev/null +++ b/examples/platform/nxp/common/gn/args.gni @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +openthread_root = + "//third_party/connectedhomeip/third_party/openthread/ot-nxp/openthread" diff --git a/examples/thermostat/nxp/rt/rw61x/.gn b/examples/thermostat/nxp/rt/rw61x/.gn index c0a26c2dc77832..cbbec24fe8c308 100644 --- a/examples/thermostat/nxp/rt/rw61x/.gn +++ b/examples/thermostat/nxp/rt/rw61x/.gn @@ -28,6 +28,9 @@ default_args = { import("//args.gni") + # Import common example GN args + import("${chip_root}/examples/platform/nxp/common/gn/args.gni") + # Import default platform configs import("${chip_root}/src/platform/nxp/rt/rw61x/args.gni") } diff --git a/scripts/build/builders/rw61x.py b/scripts/build/builders/rw61x.py index b0c67dcbac68b1..47a6d27b51aaba 100644 --- a/scripts/build/builders/rw61x.py +++ b/scripts/build/builders/rw61x.py @@ -99,6 +99,8 @@ def GnBuildArgs(self): if self.enable_thread: args.append('chip_enable_openthread=true chip_inet_config_enable_ipv4=false') + if self.enable_wifi: + args.append('openthread_root=\"//third_party/connectedhomeip/third_party/openthread/ot-nxp/openthread-br\"') if self.enable_factory_data: args.append('chip_with_factory_data=1') diff --git a/src/platform/nxp/common/DnssdImpl.cpp b/src/platform/nxp/common/DnssdImpl.cpp index 17116f21fc277f..743e4ab30cafa1 100644 --- a/src/platform/nxp/common/DnssdImpl.cpp +++ b/src/platform/nxp/common/DnssdImpl.cpp @@ -440,7 +440,7 @@ CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSr mdnsService.mInterface = ConnectivityManagerImpl().GetThreadInterface(); mdnsService.mAddressType = Inet::IPAddressType::kIPv6; - mdnsService.mAddress = MakeOptional(ToIPAddress(*ip6AddrPtr)); + mdnsService.mAddress = std::optional(ToIPAddress(*ip6AddrPtr)); // Extract TXT record SRP service txtStringPtr = otSrpServerServiceGetTxtData(service, &txtDataLen); @@ -547,7 +547,7 @@ CHIP_ERROR FromOtDnsResponseToMdnsData(otDnsServiceInfo & serviceInfo, const cha if (!otIp6IsAddressUnspecified(&serviceInfo.mHostAddress)) { mdnsService.mAddressType = Inet::IPAddressType::kIPv6; - mdnsService.mAddress = MakeOptional(ToIPAddress(serviceInfo.mHostAddress)); + mdnsService.mAddress = std::optional(ToIPAddress(serviceInfo.mHostAddress)); } // Check if TXT record was included in DNS response. diff --git a/third_party/openthread/ot-nxp b/third_party/openthread/ot-nxp index b8471857ab7b2c..f45fe4dd8687f0 160000 --- a/third_party/openthread/ot-nxp +++ b/third_party/openthread/ot-nxp @@ -1 +1 @@ -Subproject commit b8471857ab7b2c843c9ec5bc5d7e7711b2cd30a4 +Subproject commit f45fe4dd8687f0feddf063a33214c2196b463d3e From 129081a25baedbc0d3ace75b32fba4f40bdb793f Mon Sep 17 00:00:00 2001 From: Marcin Kajor <98948394+markaj-nordic@users.noreply.github.com> Date: Tue, 2 Jul 2024 16:39:15 +0200 Subject: [PATCH 07/10] [nrfconnect] Fix WiFiManager singleton implementation (#34148) * Fixed the usage of WiFiManager::Instance() * Fixed the WiFiManager's singleton by making c'tor and d'tor private Signed-off-by: Marcin Kajor --- .../wifi/ConnectivityManagerImplWiFi.cpp | 16 ++++++++-------- src/platform/nrfconnect/wifi/WiFiManager.h | 9 +++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp index 92b3532dae56f3..72c32d5ceb3f1b 100644 --- a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp +++ b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp @@ -42,7 +42,7 @@ ConnectivityManager::WiFiStationMode ConnectivityManagerImplWiFi::_GetWiFiStatio { if (mStationMode != ConnectivityManager::WiFiStationMode::kWiFiStationMode_ApplicationControlled) { - mStationMode = (WiFiManager::StationStatus::DISABLED == WiFiManager().Instance().GetStationStatus()) + mStationMode = (WiFiManager::StationStatus::DISABLED == WiFiManager::Instance().GetStationStatus()) ? ConnectivityManager::WiFiStationMode::kWiFiStationMode_Disabled : ConnectivityManager::WiFiStationMode::kWiFiStationMode_Enabled; } @@ -60,7 +60,7 @@ CHIP_ERROR ConnectivityManagerImplWiFi::_SetWiFiStationMode(ConnectivityManager: bool ConnectivityManagerImplWiFi::_IsWiFiStationEnabled(void) { - return (WiFiManager::StationStatus::DISABLED <= WiFiManager().Instance().GetStationStatus()); + return (WiFiManager::StationStatus::DISABLED <= WiFiManager::Instance().GetStationStatus()); } bool ConnectivityManagerImplWiFi::_IsWiFiStationApplicationControlled(void) @@ -70,7 +70,7 @@ bool ConnectivityManagerImplWiFi::_IsWiFiStationApplicationControlled(void) bool ConnectivityManagerImplWiFi::_IsWiFiStationConnected(void) { - return (WiFiManager::StationStatus::CONNECTED == WiFiManager().Instance().GetStationStatus()); + return (WiFiManager::StationStatus::CONNECTED == WiFiManager::Instance().GetStationStatus()); } System::Clock::Timeout ConnectivityManagerImplWiFi::_GetWiFiStationReconnectInterval(void) @@ -88,14 +88,14 @@ bool ConnectivityManagerImplWiFi::_IsWiFiStationProvisioned(void) { // from Matter perspective `provisioned` means that the supplicant has been provided // with SSID and password (doesn't matter if valid or not) - return (WiFiManager::StationStatus::CONNECTING <= WiFiManager().Instance().GetStationStatus()); + return (WiFiManager::StationStatus::CONNECTING <= WiFiManager::Instance().GetStationStatus()); } void ConnectivityManagerImplWiFi::_ClearWiFiStationProvision(void) { if (_IsWiFiStationProvisioned()) { - if (CHIP_NO_ERROR != WiFiManager().Instance().ClearStationProvisioningData()) + if (CHIP_NO_ERROR != WiFiManager::Instance().ClearStationProvisioningData()) { ChipLogError(DeviceLayer, "Cannot clear WiFi station provisioning data"); } @@ -104,9 +104,9 @@ void ConnectivityManagerImplWiFi::_ClearWiFiStationProvision(void) bool ConnectivityManagerImplWiFi::_CanStartWiFiScan() { - return (WiFiManager::StationStatus::DISABLED != WiFiManager().Instance().GetStationStatus() && - WiFiManager::StationStatus::SCANNING != WiFiManager().Instance().GetStationStatus() && - WiFiManager::StationStatus::CONNECTING != WiFiManager().Instance().GetStationStatus()); + return (WiFiManager::StationStatus::DISABLED != WiFiManager::Instance().GetStationStatus() && + WiFiManager::StationStatus::SCANNING != WiFiManager::Instance().GetStationStatus() && + WiFiManager::StationStatus::CONNECTING != WiFiManager::Instance().GetStationStatus()); } void ConnectivityManagerImplWiFi::_OnWiFiStationProvisionChange() diff --git a/src/platform/nrfconnect/wifi/WiFiManager.h b/src/platform/nrfconnect/wifi/WiFiManager.h index 0fa51e6fd6615e..05a0dd04258ce5 100644 --- a/src/platform/nrfconnect/wifi/WiFiManager.h +++ b/src/platform/nrfconnect/wifi/WiFiManager.h @@ -88,6 +88,12 @@ class Map class WiFiManager { public: + /* No copy, nor move. */ + WiFiManager(const WiFiManager &) = delete; + WiFiManager & operator=(const WiFiManager &) = delete; + WiFiManager(WiFiManager &&) = delete; + WiFiManager & operator=(WiFiManager &&) = delete; + using ScanDoneStatus = decltype(wifi_status::status); using ScanResultCallback = void (*)(const NetworkCommissioning::WiFiScanResponse &); using ScanDoneCallback = void (*)(const ScanDoneStatus &); @@ -185,6 +191,9 @@ class WiFiManager private: using NetEventHandler = void (*)(Platform::UniquePtr, size_t); + WiFiManager() = default; + ~WiFiManager() = default; + struct ConnectionParams { wifi_connect_req_params mParams; From ea235fde18654da5e664929399e395ca0ab10d1d Mon Sep 17 00:00:00 2001 From: QuentinCaldeira-eaton <164154640+QuentinCaldeira-eaton@users.noreply.github.com> Date: Tue, 2 Jul 2024 16:41:43 +0200 Subject: [PATCH 08/10] Zephyr standalone platform update (#34135) * fix zephyr build (west) * Use different Kconfig In order to let the user choose his own pack of functionality. I guess BLUETOOTH shouldn't be enable by default, because Bluetooth isn't mandatory for a Matter device Signed-off-by: Caldeira, Quentin * Remove ZephyrSocket Because zephyr has recvmsg now Signed-off-by: Caldeira, Quentin * Support ip_mreq and ip_mreqn Because Zephyr seems to not have ip_mreq, only ip_mreqn, so add an extra flag in platform config to make the choice. This issue is only meets when doing ipv4 on a Zephyr platform Signed-off-by: Caldeira, Quentin * Add missing functions to BLE Signed-off-by: Caldeira, Quentin * Add specific configs and dependencies for Zephyr platform Signed-off-by: Caldeira, Quentin * Restyled by whitespace * Restyled by clang-format * Restyled by gn * Revert "Remove ZephyrSocket" This reverts commit f283940c0312c9d4820a9e68610f319f356e45c8. Also, fix things discussed with Damian-Nordic Signed-off-by: Caldeira, Quentin * Don't use ZephyrSocket.h Since zephyr implement recvsg now Signed-off-by: Caldeira, Quentin * Remove git artifact Signed-off-by: Caldeira, Quentin * Restyled by whitespace * Restyled by clang-format * Re-add ZephyrSocket.h include Signed-off-by: Caldeira, Quentin * Remove BLE Read declarations As discussed in conversations Signed-off-by: Caldeira, Quentin * Allow net_if only with Ethernet or Wifi connection Signed-off-by: Caldeira, Quentin * Check if Ethernet is defined Because all manufactures don't implement it Signed-off-by: Caldeira, Quentin * Restyled by clang-format --------- Signed-off-by: Caldeira, Quentin Co-authored-by: Restyled.io --- config/zephyr/app/enable-gnu-std.cmake | 4 +- config/zephyr/chip-module/CMakeLists.txt | 68 ++++++++++++------ config/zephyr/chip-module/Kconfig.bt | 68 ++++++++++++++++++ config/zephyr/chip-module/Kconfig.defaults | 71 ------------------- config/zephyr/chip-module/Kconfig.mbedtls | 64 +++++++++++++++++ src/inet/InetConfig.h | 12 ++++ src/inet/UDPEndPointImplSockets.cpp | 11 +++ src/platform/Zephyr/BUILD.gn | 1 + .../Zephyr/CHIPDevicePlatformConfig.h | 40 ++++++++++- src/platform/Zephyr/CHIPPlatformConfig.h | 5 ++ .../Zephyr/ConfigurationManagerImpl.cpp | 6 ++ src/platform/Zephyr/Logging.cpp | 3 +- 12 files changed, 256 insertions(+), 97 deletions(-) create mode 100644 config/zephyr/chip-module/Kconfig.bt create mode 100644 config/zephyr/chip-module/Kconfig.mbedtls diff --git a/config/zephyr/app/enable-gnu-std.cmake b/config/zephyr/app/enable-gnu-std.cmake index 5f31e1a5c62ab8..37c18235d0f513 100644 --- a/config/zephyr/app/enable-gnu-std.cmake +++ b/config/zephyr/app/enable-gnu-std.cmake @@ -2,5 +2,5 @@ add_library(gnu17 INTERFACE) target_compile_options(gnu17 INTERFACE $<$:-std=gnu++17> - -D_SYS__PTHREADTYPES_H_) -target_link_libraries(app PRIVATE gnu17) + -D_DEFAULT_SOURCE) +target_link_libraries(app PRIVATE gnu17) \ No newline at end of file diff --git a/config/zephyr/chip-module/CMakeLists.txt b/config/zephyr/chip-module/CMakeLists.txt index 6d84a962a69cc0..575e4ff24b4827 100644 --- a/config/zephyr/chip-module/CMakeLists.txt +++ b/config/zephyr/chip-module/CMakeLists.txt @@ -39,29 +39,27 @@ endif() get_filename_component(GN_ROOT_TARGET ${CHIP_ROOT}/config/zephyr/chip-gn REALPATH) get_filename_component(COMMON_CMAKE_SOURCE_DIR ${CHIP_ROOT}/config/common/cmake REALPATH) -# Additional configuration -if (CONFIG_CHIP_PW_RPC) - set(CONFIG_CHIP_LIB_PW_RPC YES) -endif() # Get common Cmake sources include(${COMMON_CMAKE_SOURCE_DIR}/chip_gn_args.cmake) include(${COMMON_CMAKE_SOURCE_DIR}/chip_gn.cmake) -# Prepare compiler flags -matter_add_flags(-isystem${ZEPHYR_BASE}/../modules/crypto/mbedtls/include/) - if (CONFIG_POSIX_API) - matter_add_flags(-D_SYS__PTHREADTYPES_H_) + matter_add_flags(-D_DEFAULT_SOURCE) matter_add_flags(-isystem${ZEPHYR_BASE}/include/zephyr/posix) endif() +if(CONFIG_MBEDTLS) + zephyr_include_directories($) + zephyr_compile_definitions($) +endif() + zephyr_get_compile_flags(ZEPHYR_CFLAGS_C C) -matter_add_cflags(${ZEPHYR_CFLAGS_C}) +matter_add_cflags("${ZEPHYR_CFLAGS_C}") zephyr_get_compile_flags(ZEPHYR_CFLAGS_CC CXX) -matter_add_cxxflags(${ZEPHYR_CFLAGS_CC}) +matter_add_cxxflags("${ZEPHYR_CFLAGS_CC}") zephyr_get_gnu_cpp_standard(ZEPHYR_GNU_CPP_STD) -matter_add_cxxflags(${ZEPHYR_GNU_CPP_STD}) +matter_add_cxxflags("${ZEPHYR_GNU_CPP_STD}") # Set up custom OpenThread configuration @@ -81,21 +79,52 @@ matter_common_gn_args( DEBUG CONFIG_DEBUG LIB_SHELL CONFIG_CHIP_LIB_SHELL LIB_TESTS CONFIG_CHIP_BUILD_TESTS - LIB_PW_RPC CONFIG_CHIP_PW_RPC PROJECT_CONFIG ${CONFIG_CHIP_PROJECT_CONFIG} ) -matter_add_gn_arg_string("zephyr_ar" ${CMAKE_AR}) -matter_add_gn_arg_string("zephyr_cc" ${CMAKE_C_COMPILER}) -matter_add_gn_arg_string("zephyr_cxx" ${CMAKE_CXX_COMPILER}) -matter_add_gn_arg_bool ("chip_enable_openthread" CONFIG_NET_L2_OPENTHREAD) -matter_add_gn_arg_bool ("chip_openthread_ftd" CONFIG_OPENTHREAD_FTD) -matter_add_gn_arg_bool ("chip_inet_config_enable_ipv4" CONFIG_NET_IPV4) -matter_add_gn_arg_bool ("chip_inet_config_enable_tcp_endpoint" CONFIG_CHIP_BUILD_TESTS) + +matter_add_gn_arg_string("zephyr_ar" ${CMAKE_AR}) +matter_add_gn_arg_string("zephyr_cc" ${CMAKE_C_COMPILER}) +matter_add_gn_arg_string("zephyr_cxx" ${CMAKE_CXX_COMPILER}) +matter_add_gn_arg_bool ("chip_logging" CONFIG_LOG) +matter_add_gn_arg_bool ("chip_error_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 1) +matter_add_gn_arg_bool ("chip_progress_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 3) +matter_add_gn_arg_bool ("chip_detail_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 4) +matter_add_gn_arg_bool ("chip_automation_logging" FALSE) +matter_add_gn_arg_bool ("chip_enable_openthread" CONFIG_NET_L2_OPENTHREAD) +matter_add_gn_arg_bool ("chip_openthread_ftd" CONFIG_OPENTHREAD_FTD) +matter_add_gn_arg_bool ("chip_inet_config_enable_ipv4" CONFIG_CHIP_IPV4) +matter_add_gn_arg_bool ("chip_enable_wifi" CONFIG_WIFI) +matter_add_gn_arg_bool ("chip_config_network_layer_ble" CONFIG_BT) +matter_add_gn_arg_bool ("chip_mdns_minimal" CONFIG_WIFI) +matter_add_gn_arg_bool ("chip_mdns_minimal" CONFIG_NET_L2_ETHERNET) +matter_add_gn_arg_bool ("chip_mdns_platform" CONFIG_NET_L2_OPENTHREAD) +matter_add_gn_arg_bool ("chip_inet_config_enable_tcp_endpoint" CONFIG_CHIP_BUILD_TESTS) +matter_add_gn_arg_bool ("chip_inet_config_enable_udp_endpoint" CONFIG_NET_UDP) +matter_add_gn_arg_bool ("chip_inet_config_enable_tcp_endpoint" CONFIG_NET_TCP) +matter_add_gn_arg_bool ("chip_malloc_sys_heap" CONFIG_CHIP_MALLOC_SYS_HEAP) + if (CONFIG_CHIP_ENABLE_DNSSD_SRP) matter_add_gn_arg_string("chip_mdns" "platform") endif() +if(CONFIG_WIFI) + matter_add_gn_arg_string("chip_mdns" "minimal") +elseif (CONFIG_NET_L2_ETHERNET) + matter_add_gn_arg_string("chip_mdns" "minimal") +elseif (CONFIG_NET_L2_OPENTHREAD) + matter_add_gn_arg_string("chip_mdns" "platform") +else() + matter_add_gn_arg_string("chip_mdns" "none") +endif() + +if (CONFIG_CHIP_PW_RPC) + set(PIGWEED_DIR "//third_party/pigweed/repo") + matter_add_gn_arg_string("pw_assert_BACKEND" ${PIGWEED_DIR}/pw_assert_log:check_backend) + matter_add_gn_arg_string("pw_log_BACKEND" ${PIGWEED_DIR}/pw_log_basic) + matter_add_gn_arg("pw_build_LINK_DEPS" [\"${PIGWEED_DIR}/pw_assert:impl\",\ \"${PIGWEED_DIR}/pw_log:impl\"]) +endif() + matter_generate_args_tmp_file() # ============================================================================== @@ -103,7 +132,6 @@ matter_generate_args_tmp_file() # ============================================================================== matter_build(chip LIB_SHELL ${CONFIG_CHIP_LIB_SHELL} - LIB_PW_RPC ${CONFIG_CHIP_PW_RPC} LIB_TESTS ${CONFIG_CHIP_BUILD_TESTS} GN_DEPENDENCIES kernel ) diff --git a/config/zephyr/chip-module/Kconfig.bt b/config/zephyr/chip-module/Kconfig.bt new file mode 100644 index 00000000000000..547224549df1e6 --- /dev/null +++ b/config/zephyr/chip-module/Kconfig.bt @@ -0,0 +1,68 @@ +# +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Bluetooth Low Energy configs +config BT + bool + default y + +config BT_PERIPHERAL + bool + default y + +config BT_PERIPHERAL_PREF_MIN_INT + int + default 36 + +config BT_PERIPHERAL_PREF_MAX_INT + int + default 36 + +config BT_GAP_AUTO_UPDATE_CONN_PARAMS + bool + default y + +config BT_GATT_DYNAMIC_DB + bool + default y + +config BT_DEVICE_NAME_DYNAMIC + bool + default y + +config BT_DEVICE_NAME_MAX + int + default 15 + +config BT_MAX_CONN + int + default 1 + +config BT_L2CAP_TX_MTU + int + default 247 + +config BT_BUF_ACL_RX_SIZE + int + default 251 + +config BT_BUF_ACL_TX_SIZE + int + default 251 + +config BT_RX_STACK_SIZE + int + default 1200 \ No newline at end of file diff --git a/config/zephyr/chip-module/Kconfig.defaults b/config/zephyr/chip-module/Kconfig.defaults index d21562cd4d3e16..f092de983eade1 100644 --- a/config/zephyr/chip-module/Kconfig.defaults +++ b/config/zephyr/chip-module/Kconfig.defaults @@ -20,26 +20,6 @@ if CHIP -config LOG - bool - default y - -if LOG - -choice LOG_MODE - default LOG_MODE_MINIMAL -endchoice - -choice MATTER_LOG_LEVEL_CHOICE - default MATTER_LOG_LEVEL_DBG -endchoice - -config LOG_DEFAULT_LEVEL - int - default 2 - -endif - # disable synchronous printk to avoid blocking IRQs which # may affect time sensitive components config PRINTK_SYNC @@ -119,58 +99,7 @@ config NET_BUF_TX_COUNT int default 80 -# Bluetooth Low Energy configs -config BT - bool - default y - -config BT_PERIPHERAL - bool - default y - -config BT_PERIPHERAL_PREF_MIN_INT - int - default 36 - -config BT_PERIPHERAL_PREF_MAX_INT - int - default 36 - -config BT_GAP_AUTO_UPDATE_CONN_PARAMS - bool - default y - -config BT_GATT_DYNAMIC_DB - bool - default y - -config BT_DEVICE_NAME_DYNAMIC - bool - default y - -config BT_DEVICE_NAME_MAX - int - default 15 -config BT_MAX_CONN - int - default 1 - -config BT_L2CAP_TX_MTU - int - default 247 - -config BT_BUF_ACL_RX_SIZE - int - default 251 - -config BT_BUF_ACL_TX_SIZE - int - default 251 - -config BT_RX_STACK_SIZE - int - default 1200 config CHIP_OTA_REQUESTOR bool diff --git a/config/zephyr/chip-module/Kconfig.mbedtls b/config/zephyr/chip-module/Kconfig.mbedtls new file mode 100644 index 00000000000000..3e4fdc1895db3c --- /dev/null +++ b/config/zephyr/chip-module/Kconfig.mbedtls @@ -0,0 +1,64 @@ +# +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +if CHIP + +config MBEDTLS + default y + +config MBEDTLS_ENTROPY_ENABLED + default y + +config MBEDTLS_ENTROPY_ENABLED + default y + +config MBEDTLS_ZEPHYR_ENTROPY + default y + +config MBEDTLS_ENABLE_HEAP + default y + +config MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + default y + +config MBEDTLS_ECP_ALL_ENABLED + default y + +config MBEDTLS_ECP_C + default y + +config MBEDTLS_PKCS5_C + default y + +config MBEDTLS_HKDF_C + default y + +config MBEDTLS_CIPHER_CCM_ENABLED + default y + +config MBEDTLS_CTR_DRBG_ENABLED + default y + +config MBEDTLS_CIPHER_AES_ENABLED + default y + +config MBEDTLS_ECDH_C + default y + +config MBEDTLS_ECDSA_C + default y + +endif #CHIP \ No newline at end of file diff --git a/src/inet/InetConfig.h b/src/inet/InetConfig.h index c3653a4216110f..e84276c51411ed 100644 --- a/src/inet/InetConfig.h +++ b/src/inet/InetConfig.h @@ -283,4 +283,16 @@ #define HAVE_SO_BINDTODEVICE 0 #endif +/** + * @def INET_CONFIG_UDP_SOCKET_MREQN + * + * @brief + * Should be set to 1 if your platform can handle struct ip_mreqn, + * mandatory in UDPEndPointSocket.cpp + */ + +#ifndef INET_CONFIG_UDP_SOCKET_MREQN +#define INET_CONFIG_UDP_SOCKET_MREQN 0 +#endif + // clang-format on diff --git a/src/inet/UDPEndPointImplSockets.cpp b/src/inet/UDPEndPointImplSockets.cpp index f1831c475f2cc5..c80db4d771b10f 100644 --- a/src/inet/UDPEndPointImplSockets.cpp +++ b/src/inet/UDPEndPointImplSockets.cpp @@ -785,11 +785,22 @@ CHIP_ERROR UDPEndPointImplSockets::IPv4JoinLeaveMulticastGroupImpl(InterfaceId a interfaceAddr.s_addr = htonl(INADDR_ANY); } +#if INET_CONFIG_UDP_SOCKET_MREQN + struct ip_mreqn lMulticastRequest; + memset(&lMulticastRequest, 0, sizeof(lMulticastRequest)); + lMulticastRequest.imr_ifindex = aInterfaceId.GetPlatformInterface(); /* Network interface index */ + lMulticastRequest.imr_address = interfaceAddr; /* IP address of local interface */ + lMulticastRequest.imr_multiaddr = aAddress.ToIPv4(); /* IP multicast group address*/ + +#else + struct ip_mreq lMulticastRequest; memset(&lMulticastRequest, 0, sizeof(lMulticastRequest)); lMulticastRequest.imr_interface = interfaceAddr; lMulticastRequest.imr_multiaddr = aAddress.ToIPv4(); +#endif + const int command = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP; if (setsockopt(mSocket, IPPROTO_IP, command, &lMulticastRequest, sizeof(lMulticastRequest)) != 0) { diff --git a/src/platform/Zephyr/BUILD.gn b/src/platform/Zephyr/BUILD.gn index f271d2ea7edf74..f1d9bdb2cef34f 100644 --- a/src/platform/Zephyr/BUILD.gn +++ b/src/platform/Zephyr/BUILD.gn @@ -38,6 +38,7 @@ static_library("Zephyr") { "ConnectivityManagerImpl.h", "DiagnosticDataProviderImpl.cpp", "DiagnosticDataProviderImpl.h", + "DiagnosticDataProviderImplGetter.cpp", "InetPlatformConfig.h", "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", diff --git a/src/platform/Zephyr/CHIPDevicePlatformConfig.h b/src/platform/Zephyr/CHIPDevicePlatformConfig.h index e7622f60ddf9fc..687e743444b9d9 100644 --- a/src/platform/Zephyr/CHIPDevicePlatformConfig.h +++ b/src/platform/Zephyr/CHIPDevicePlatformConfig.h @@ -46,9 +46,41 @@ #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0 #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 -#define CHIP_DEVICE_CONFIG_ENABLE_THREAD CONFIG_NET_L2_OPENTHREAD - -#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE CONFIG_BT +// Check if Zephyr app use NET_L2_OPENTHREAD +#ifndef CHIP_DEVICE_CONFIG_ENABLE_THREAD +#ifdef CONFIG_NET_L2_OPENTHREAD +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD 1 +#else +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD 0 +#endif // CONFIG_NET_L2_OPENTHREAD +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD + +// Check if Zephyr app use BT +#ifndef CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#ifdef CONFIG_BT +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 +#else +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 0 +#endif // CONFIG_BT +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +// Check if Zephyr app use WIFI +#ifndef CHIP_DEVICE_CONFIG_ENABLE_WIFI +#ifdef CONFIG_WIFI +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI 1 +#else +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI 0 +#endif // CONFIG_WIFI +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI +// Check if Zephyr app use NET_L2_ETHERNET + +#ifndef CHIP_DEVICE_CONFIG_ENABLE_ETHERNET +#ifdef CONFIG_NET_L2_ETHERNET +#define CHIP_DEVICE_CONFIG_ENABLE_ETHERNET 1 +#else +#define CHIP_DEVICE_CONFIG_ENABLE_ETHERNET 0 +#endif // CONFIG_NET_L2_ETHERNET +#endif // CHIP_DEVICE_CONFIG_ENABLE_ETHERNET // ========== Platform-specific Configuration ========= @@ -75,6 +107,8 @@ #if !defined(CONFIG_CHIP_MALLOC_SYS_HEAP) && defined(CONFIG_NEWLIB_LIBC) /// Use mallinfo() to obtain the heap usage statistics exposed by SoftwareDiagnostics cluster attributes. #define CHIP_DEVICE_CONFIG_HEAP_STATISTICS_MALLINFO 1 +#else +#define CHIP_DEVICE_CONFIG_HEAP_STATISTICS_MALLINFO 0 #endif // !defined(CONFIG_CHIP_MALLOC_SYS_HEAP) && defined(CONFIG_NEWLIB_LIBC) #endif // CHIP_DEVICE_CONFIG_HEAP_STATISTICS_MALLINFO diff --git a/src/platform/Zephyr/CHIPPlatformConfig.h b/src/platform/Zephyr/CHIPPlatformConfig.h index c463fb21da88f2..aabad7a57a2d9e 100644 --- a/src/platform/Zephyr/CHIPPlatformConfig.h +++ b/src/platform/Zephyr/CHIPPlatformConfig.h @@ -52,4 +52,9 @@ #ifndef CHIP_CONFIG_MAX_FABRICS #define CHIP_CONFIG_MAX_FABRICS 5 + +#define INET_CONFIG_UDP_SOCKET_MREQN 1 + +#define CHIP_SYSTEM_CONFIG_USE_ZEPHYR_SOCKET_EXTENSIONS 0 + #endif diff --git a/src/platform/Zephyr/ConfigurationManagerImpl.cpp b/src/platform/Zephyr/ConfigurationManagerImpl.cpp index ad70b34da3f30b..2b1070af88ee77 100644 --- a/src/platform/Zephyr/ConfigurationManagerImpl.cpp +++ b/src/platform/Zephyr/ConfigurationManagerImpl.cpp @@ -32,6 +32,12 @@ #include "InetUtils.h" +#ifdef CHIP_DEVICE_CONFIG_ENABLE_ETHERNET +#if (CHIP_DEVICE_CONFIG_ENABLE_WIFI) || (CHIP_DEVICE_CONFIG_ENABLE_ETHERNET) +#include +#endif //(CHIP_DEVICE_CONFIG_ENABLE_WIFI) || (CHIP_DEVICE_CONFIG_ENABLE_ETHERNET) +#endif // CHIP_DEVICE_CONFIG_ENABLE_ETHERNET + #include #include diff --git a/src/platform/Zephyr/Logging.cpp b/src/platform/Zephyr/Logging.cpp index a5c1ad7b063d03..4f7322534e331e 100644 --- a/src/platform/Zephyr/Logging.cpp +++ b/src/platform/Zephyr/Logging.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -41,7 +42,7 @@ namespace Platform { * CHIP log output function. */ -void LogV(const char * module, uint8_t category, const char * msg, va_list v) +void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v) { char formattedMsg[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE]; snprintfcb(formattedMsg, sizeof(formattedMsg), "[%s]", module); From fdb71dcf1f234baffddbb04e1baefc2755d35192 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Tue, 2 Jul 2024 07:43:22 -0700 Subject: [PATCH 09/10] Add build docs for Fabric-Admin and Fabric-Bridge-App (#34122) * Add build doc for Fabric-Admin and Fabric-Bridge-App * Update examples/fabric-admin/README.md Co-authored-by: saurabhst --------- Co-authored-by: saurabhst Co-authored-by: Andrei Litvin --- docs/examples/index.md | 9 ++++ examples/fabric-admin/README.md | 53 ++++++++++++++++++++++ examples/fabric-bridge-app/linux/README.md | 47 ++++++++++++++++--- 3 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 examples/fabric-admin/README.md diff --git a/docs/examples/index.md b/docs/examples/index.md index 6e7a0b4b88ca1b..446c94f6f61f3b 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -85,6 +85,15 @@ darwin-framework-tool/README energy-management-app/**/README ``` +## Fabric Admin example + +```{toctree} +:glob: +:maxdepth: 1 + +fabric-admin/README +``` + ## Fabric Bridge example ```{toctree} diff --git a/examples/fabric-admin/README.md b/examples/fabric-admin/README.md new file mode 100644 index 00000000000000..da2a4d6b21684e --- /dev/null +++ b/examples/fabric-admin/README.md @@ -0,0 +1,53 @@ +# Matter Fabric Administrator Example + +An example application that supports synchronization of devices across fabrics +fabrics. + +--- + +- [Building the Example Application](#building-the-example-application) + +--- + +## Building the Example Application + +For Linux host example: + +``` +./scripts/examples/gn_build_example.sh examples/fabric-admin out/debug/standalone chip_config_network_layer_ble=false 'import("//with_pw_rpc.gni")' +``` + +For Raspberry Pi 4 example: + +### Pull Docker Images + +``` +docker pull connectedhomeip/chip-build-vscode:latest +``` + +### Run docker + +``` +docker run -it -v ~/connectedhomeip:/var/connectedhomeip connectedhomeip/chip-build-vscode:latest /bin/bash +``` + +### Build + +``` +cd /var/connectedhomeip + +git config --global --add safe.directory /var/connectedhomeip +git config --global --add safe.directory /var/connectedhomeip/third_party/pigweed/repo +git config --global --add safe.directory /var/connectedhomeip/examples/common/QRCode/repo + +./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --target linux-arm64-fabric-admin-clang-rpc \ + build" +``` + +### Transfer the fabric-admin binary to a Raspberry Pi + +``` +scp ./fabric-admin ubuntu@xxx.xxx.xxx.xxx:/home/ubuntu +``` diff --git a/examples/fabric-bridge-app/linux/README.md b/examples/fabric-bridge-app/linux/README.md index 212f6963cd4577..6d830cdd987c33 100644 --- a/examples/fabric-bridge-app/linux/README.md +++ b/examples/fabric-bridge-app/linux/README.md @@ -88,12 +88,45 @@ defined: - Build the example application: - ```sh - cd ~/connectedhomeip/examples/fabric-bridge-app/linux - git submodule update --init - source third_party/connectedhomeip/scripts/activate.sh - gn gen out/debug - ninja -C out/debug + ### For Linux host example: + + ``` + ./scripts/examples/gn_build_example.sh examples/fabric-bridge-app/linux out/debug/standalone chip_config_network_layer_ble=false 'import("//with_pw_rpc.gni")' + ``` + + ### For Raspberry Pi 4 example: + + Pull Docker Images + + ``` + docker pull connectedhomeip/chip-build-vscode:latest + ``` + + Run docker + + ``` + docker run -it -v ~/connectedhomeip:/var/connectedhomeip connectedhomeip/chip-build-vscode:latest /bin/bash + ``` + + Build + + ``` + cd /var/connectedhomeip + + git config --global --add safe.directory /var/connectedhomeip + git config --global --add safe.directory /var/connectedhomeip/third_party/pigweed/repo + git config --global --add safe.directory /var/connectedhomeip/examples/common/QRCode/repo + + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --target linux-arm64-fabric-bridge-no-ble-clang-rpc \ + build" + ``` + + Transfer the fabric-bridge-app binary to a Raspberry Pi + + ``` + scp ./fabric-bridge-app ubuntu@xxx.xxx.xxx.xxx:/home/ubuntu ``` - To delete generated executable, libraries and object files use: @@ -116,4 +149,4 @@ defined: sudo out/debug/fabric-bridge-app ``` -- Test the device using ChipDeviceController on your laptop / workstation etc. +- Test the device using FabricAdmin on your laptop / workstation etc. From 005f1b49f179d7af90b129fddf5aad466767e0b8 Mon Sep 17 00:00:00 2001 From: Jakub Latusek Date: Tue, 2 Jul 2024 16:52:26 +0200 Subject: [PATCH 10/10] Update callback (#34147) --- src/lib/core/tests/TestCHIPCallback.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/core/tests/TestCHIPCallback.cpp b/src/lib/core/tests/TestCHIPCallback.cpp index 111a8a73671802..88483dce445bc1 100644 --- a/src/lib/core/tests/TestCHIPCallback.cpp +++ b/src/lib/core/tests/TestCHIPCallback.cpp @@ -201,7 +201,7 @@ TEST_F(TestCHIPCallback, NotifierTest) { int n = 1; Callback cb(reinterpret_cast(increment_by), &n); - Callback cancelcb(reinterpret_cast(canceler), cb.Cancel()); + Callback cancelcb([](void * call, int) { canceler(reinterpret_cast(call)); }, cb.Cancel()); // safe to call anytime cb.Cancel();