From 05d79a2fe28af1bd68103148d69cb28c3422135b Mon Sep 17 00:00:00 2001
From: Jean-Francois Penven <67962328+jepenven-silabs@users.noreply.github.com>
Date: Mon, 24 Apr 2023 10:51:53 -0400
Subject: [PATCH] Add Silabs Platform abstraction (#26196)

---
 src/platform/silabs/SiWx917/BUILD.gn          |  3 +
 src/platform/silabs/efr32/BUILD.gn            |  3 +
 .../silabs/platformAbstraction/GSDK_SPAM.cpp  | 76 +++++++++++++++++++
 .../platformAbstraction/SilabsPlatform.h      | 63 +++++++++++++++
 .../platformAbstraction/SilabsPlatformBase.h  | 56 ++++++++++++++
 .../platformAbstraction/WiseMCU_SPAM.cpp      | 66 ++++++++++++++++
 6 files changed, 267 insertions(+)
 create mode 100644 src/platform/silabs/platformAbstraction/GSDK_SPAM.cpp
 create mode 100644 src/platform/silabs/platformAbstraction/SilabsPlatform.h
 create mode 100644 src/platform/silabs/platformAbstraction/SilabsPlatformBase.h
 create mode 100644 src/platform/silabs/platformAbstraction/WiseMCU_SPAM.cpp

diff --git a/src/platform/silabs/SiWx917/BUILD.gn b/src/platform/silabs/SiWx917/BUILD.gn
index fadfbbd1177f39..346c4ad20652ff 100644
--- a/src/platform/silabs/SiWx917/BUILD.gn
+++ b/src/platform/silabs/SiWx917/BUILD.gn
@@ -53,6 +53,9 @@ static_library("SiWx917") {
     "${silabs_platform_dir}/SilabsConfig.cpp",
     "${silabs_platform_dir}/SilabsConfig.h",
     "${silabs_platform_dir}/SystemPlatformConfig.h",
+    "${silabs_platform_dir}/platformAbstraction/SilabsPlatform.h",
+    "${silabs_platform_dir}/platformAbstraction/SilabsPlatformBase.h",
+    "${silabs_platform_dir}/platformAbstraction/WiseMCU_SPAM.cpp",
     "../../FreeRTOS/SystemTimeSupport.cpp",
     "../../SingletonConfigurationManager.cpp",
     "BLEManagerImpl.cpp",
diff --git a/src/platform/silabs/efr32/BUILD.gn b/src/platform/silabs/efr32/BUILD.gn
index 61a1ddc26fc7e2..7b80bf07111915 100644
--- a/src/platform/silabs/efr32/BUILD.gn
+++ b/src/platform/silabs/efr32/BUILD.gn
@@ -57,6 +57,9 @@ static_library("efr32") {
     "${silabs_platform_dir}/SilabsConfig.cpp",
     "${silabs_platform_dir}/SilabsConfig.h",
     "${silabs_platform_dir}/SystemPlatformConfig.h",
+    "${silabs_platform_dir}/platformAbstraction/GSDK_SPAM.cpp",
+    "${silabs_platform_dir}/platformAbstraction/SilabsPlatform.h",
+    "${silabs_platform_dir}/platformAbstraction/SilabsPlatformBase.h",
     "../../FreeRTOS/SystemTimeSupport.cpp",
     "../../SingletonConfigurationManager.cpp",
     "ConfigurationManagerImpl.cpp",
diff --git a/src/platform/silabs/platformAbstraction/GSDK_SPAM.cpp b/src/platform/silabs/platformAbstraction/GSDK_SPAM.cpp
new file mode 100644
index 00000000000000..e0f954e101a90d
--- /dev/null
+++ b/src/platform/silabs/platformAbstraction/GSDK_SPAM.cpp
@@ -0,0 +1,76 @@
+/*
+ *    Copyright (c) 2023 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 "init_efrPlatform.h"
+#include <platform/silabs/platformAbstraction/SilabsPlatform.h>
+
+namespace chip {
+namespace DeviceLayer {
+namespace Silabs {
+
+SilabsPlatform SilabsPlatform::sSilabsPlatformAbstractionManager;
+
+CHIP_ERROR SilabsPlatform::Init(void)
+{
+    init_efrPlatform();
+    return CHIP_NO_ERROR;
+}
+
+#ifdef ENABLE_WSTK_LEDS
+
+#include "sl_simple_led_instances.h"
+
+void SilabsPlatform::InitLed(void)
+{
+    sl_simple_led_init_instances();
+}
+
+CHIP_ERROR SilabsPlatform::SetLed(bool state, uint8_t led)
+{
+    if (led >= SL_SIMPLE_LED_COUNT)
+    {
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    (state) ? sl_led_turn_on(SL_SIMPLE_LED_INSTANCE(led)) : sl_led_turn_off(SL_SIMPLE_LED_INSTANCE(led));
+    return CHIP_NO_ERROR;
+}
+
+bool SilabsPlatform::GetLedState(uint8_t led)
+{
+    if (led >= SL_SIMPLE_LED_COUNT)
+    {
+        return 0;
+    }
+
+    return sl_led_get_state(SL_SIMPLE_LED_INSTANCE(led));
+}
+
+CHIP_ERROR SilabsPlatform::ToggleLed(uint8_t led)
+{
+    if (led >= SL_SIMPLE_LED_COUNT)
+    {
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+    sl_led_toggle(SL_SIMPLE_LED_INSTANCE(led));
+    return CHIP_NO_ERROR;
+}
+#endif // ENABLE_WSTK_LEDS
+
+} // namespace Silabs
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/silabs/platformAbstraction/SilabsPlatform.h b/src/platform/silabs/platformAbstraction/SilabsPlatform.h
new file mode 100644
index 00000000000000..f5dabc9d4bd72a
--- /dev/null
+++ b/src/platform/silabs/platformAbstraction/SilabsPlatform.h
@@ -0,0 +1,63 @@
+/*
+ *    Copyright (c) 2023 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 <platform/silabs/platformAbstraction/SilabsPlatformBase.h>
+#include <stdint.h>
+#include <stdio.h>
+
+namespace chip {
+namespace DeviceLayer {
+namespace Silabs {
+
+class SilabsPlatform : virtual public SilabsPlatformAbstractionBase
+{
+
+public:
+    // Generic Peripherical methods
+    CHIP_ERROR Init(void) override;
+
+    // LEDS
+#ifdef ENABLE_WSTK_LEDS
+    void InitLed(void) override;
+    CHIP_ERROR SetLed(bool state, uint8_t led) override;
+    bool GetLedState(uint8_t led) override;
+    CHIP_ERROR ToggleLed(uint8_t led) override;
+#endif
+
+private:
+    friend SilabsPlatform & GetPlatform(void);
+
+    // To make underlying SDK thread safe
+    void SilabsPlatformLock(void);
+    void SilabsPlatformUnlock(void);
+
+    SilabsPlatform(){};
+    virtual ~SilabsPlatform() = default;
+
+    static SilabsPlatform sSilabsPlatformAbstractionManager;
+};
+
+inline SilabsPlatform & GetPlatform(void)
+{
+    return SilabsPlatform::sSilabsPlatformAbstractionManager;
+}
+
+} // namespace Silabs
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h b/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h
new file mode 100644
index 00000000000000..548fffac9e3599
--- /dev/null
+++ b/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h
@@ -0,0 +1,56 @@
+/*
+ *    Copyright (c) 2023 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 <stdint.h>
+#include <stdio.h>
+
+#include <lib/core/CHIPError.h>
+
+namespace chip {
+namespace DeviceLayer {
+namespace Silabs {
+
+class SilabsPlatformAbstractionBase
+{
+
+public:
+    // Generic Peripherical methods
+    virtual CHIP_ERROR Init(void) = 0;
+    virtual CHIP_ERROR InitLCD() { return CHIP_ERROR_NOT_IMPLEMENTED; }
+    virtual CHIP_ERROR SetGPIO(uint32_t port, uint32_t pin, bool state) { return CHIP_ERROR_NOT_IMPLEMENTED; }
+    virtual bool GetGPIO(uint32_t port, uint32_t pin) { return false; }
+
+    // Buttons
+
+    // LEDS
+    virtual void InitLed(void) {}
+    virtual CHIP_ERROR SetLed(bool state, uint8_t led) { return CHIP_ERROR_NOT_IMPLEMENTED; }
+    virtual bool GetLedState(uint8_t led) { return 0; }
+    virtual CHIP_ERROR ToggleLed(uint8_t led) { return CHIP_ERROR_NOT_IMPLEMENTED; }
+
+    // BLE Specific Method
+
+protected:
+    SilabsPlatformAbstractionBase(){};
+    ~SilabsPlatformAbstractionBase(){};
+};
+
+} // namespace Silabs
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/platform/silabs/platformAbstraction/WiseMCU_SPAM.cpp b/src/platform/silabs/platformAbstraction/WiseMCU_SPAM.cpp
new file mode 100644
index 00000000000000..97004960f94d06
--- /dev/null
+++ b/src/platform/silabs/platformAbstraction/WiseMCU_SPAM.cpp
@@ -0,0 +1,66 @@
+/*
+ *    Copyright (c) 2023 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 <platform/silabs/platformAbstraction/SilabsPlatform.h>
+
+#include "init_ccpPlatform.h"
+
+// TODO add includes ?
+extern "C" void RSI_Board_LED_Set(int, bool);
+extern "C" void RSI_Board_LED_Toggle(int);
+
+namespace chip {
+namespace DeviceLayer {
+namespace Silabs {
+
+SilabsPlatform SilabsPlatform::sSilabsPlatformAbstractionManager;
+
+CHIP_ERROR SilabsPlatform::Init(void)
+{
+    init_ccpPlatform();
+}
+
+#ifdef ENABLE_WSTK_LEDS
+void SilabsPlatform::InitLed(void)
+{
+    // TODO ?
+    SilabsPlatformAbstractionBase::InitLed();
+}
+
+CHIP_ERROR SilabsPlatform::SetLed(bool state, uint8_t led) override
+{
+    // TODO add range check ?
+    RSI_Board_LED_Set(led, state);
+    return CHIP_NO_ERROR;
+}
+
+bool SilabsPlatform::GetLedState(uint8_t led)
+{
+    // TODO ?
+    return SilabsPlatformAbstractionBase::GetLedState(led);
+}
+
+CHIP_ERROR SilabsPlatform::ToggleLed(uint8_t led) override
+{
+    // TODO add range check ?
+    RSI_Board_LED_Toggle(led) return CHIP_NO_ERROR;
+}
+#endif // ENABLE_WSTK_LEDS
+
+} // namespace Silabs
+} // namespace DeviceLayer
+} // namespace chip