diff --git a/README.md b/README.md
index cdc4acca..7411671f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Third Party Hardware Drivers #
-[![Version Badge](https://img.shields.io/badge/-v1.3.0-green)](https://github.com/SiliconLabs/third_party_hw_drivers_extension/releases)
+[![Version Badge](https://img.shields.io/badge/-v1.4.0-green)](https://github.com/SiliconLabs/third_party_hw_drivers_extension/releases)
[![GSDK Badge](https://img.shields.io/badge/GSDK-v4.2.3-green)](https://github.com/SiliconLabs/gecko_sdk/releases)
![License badge](https://img.shields.io/badge/License-Zlib-green)
@@ -46,9 +46,25 @@ A full list of all drivers in this repository is defined below:
| gpsclick_lea6s | [Click Here](./driver/public/mikroe/gpsclick_lea6s) | [Click Here](./app/example/mikroe_gpsclick_lea6s) | [Click Here](./app/documentation/example/mikroe_gpsclick_lea6s) |
| temphum15_sht40 | [Click Here](./driver/public/mikroe/temphum15_sht40) | [Click Here](./app/example/mikroe_temphum15_sht40) | [Click Here](./app/documentation/example/mikroe_temphum15_sht40) |
| irthermo3_mlx90632 | [Click Here](./driver/public/mikroe/irthermo3_mlx90632) | [Click Here](./app/example/mikroe_irthermo3_mlx90632) | [Click Here](./app/documentation/example/mikroe_irthermo3_mlx90632) |
+| stepper_a3967 | [Click Here](./driver/public/silabs/stepper_a3967) | [Click Here](./app/example/mikroe_stepper_a3967) | [Click Here](./app/documentation/example/mikroe_stepper_a3967) |
| stepper2_a4988 | [Click Here](./driver/public/mikroe/stepper2_a4988) | [Click Here](./app/example/mikroe_stepper2_a4988) | [Click Here](./app/documentation/example/mikroe_stepper2_a4988) |
| dcmotor3_tb6549fg | [Click Here](./driver/public/mikroe/dcmotor3_tb6549fg) | [Click Here](./app/example/mikroe_dcmotor3_tb6549fg) | [Click Here](./app/documentation/example/mikroe_dcmotor3_tb6549fg) |
| environmental_bme280_ccs811 | [Click Here](./driver/public/silabs/environmental_bme280_ccs811) | [Click Here](./app/example/sparkfun_environmental_bme280_ccs811) | [Click Here](./app/documentation/example/sparkfun_environmental_bme280_ccs811) |
+| oledc_ssd1351 | [Click Here](./driver/public/mikroe/oledc_ssd1351) | [Click Here](./app/example/mikroe_oledc_ssd1351) | [Click Here](./app/documentation/example/mikroe_oledc_ssd1351) |
+| pressure_dps310 | [Click Here](./driver/public/mikroe/pressure3_dps310) | [Click Here](./app/example/mikroe_pressure3_dps310) | [Click Here](./app/documentation/example/mikroe_pressure3_dps310) |
+| lte_iot_2 | [Click Here](./driver/public/mikroe/lte_iot2_bg96) | [Click Here](./app/example/mikroe_lte_iot2_bg96) | [Click Here](./app/documentation/example/mikroe_lte_iot2_bg96) |
+| e_paper | [Click Here](./driver/public/mikroe/e_paper) | [Click Here](./app/example/mikroe_e_paper) | [Click Here](./app/documentation/example/mikroe_e_paper) |
+| ir_array_amg88xx | [Click Here](./driver/public/silabs/ir_array_amg88xx) | [Click Here](./app/example/sparkfun_ir_array_amg88xx) | [Click Here](./app/documentation/example/sparkfun_ir_array_amg88xx) |
+| nfc2_pn7150 | [Click Here](./driver/public/mikroe/nfc2_pn7150) | [Click Here](./app/example/mikroe_nfc2_pn7150) | [Click Here](./app/documentation/example/mikroe_nfc2_pn7150) |
+| nfc2_pn7150_t2t_read | [Click Here](./driver/public/silabs/services_nfc) | [Click Here](./app/example/mikroe_nfc2_pn7150_nci_t2t_read) | [Click Here](./app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read) |
+| nfc2_pn7150_t2t_write | [Click Here](./driver/public/silabs/services_nfc) | [Click Here](./app/example/mikroe_nfc2_pn7150_nci_t2t_write) | [Click Here](./app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write) |
+| ir_generate | [Click Here](./driver/public/silabs/ir_generate) | [Click Here](./app/example/silabs_ir_generate) | [Click Here](./app/documentation/example/silabs_ir_generate) |
+| triac | [Click Here](./driver/public/silabs/triac) | [Click Here](./app/example/silabs_triac) | [Click Here](./app/documentation/example/silabs_triac) |
+| mikroe_microsd | [Click Here](./driver/public/mikroe/mikroe_microsd) | [Click Here](./app/example/mikroe_microsd) | [Click Here](./app/documentation/example/mikroe_microsd) |
+| pir_ira_s210st01 | [Click Here](./driver/public/silabs/pir_ira_s210st01) | [Click Here](./app/example/silabs_pir_ira_s210st01) | [Click Here](./app/documentation/example/silabs_pir_ira_s210st01) |
+| rf_meter_ad8318 | [Click Here](./driver/public/mikroe/rf_meter_ad8318) | [Click Here](./app/example/mikroe_rf_meter_ad8318) | [Click Here](./app/documentation/example/mikroe_rf_meter_ad8318) |
+| nfctag2_nt3h2111 | [Click Here](./driver/public/silabs/nfctag2_nt3h2111) | [Click Here](./app/example/mikroe_nfctag2_nt3h2111) | [Click Here](./app/documentation/example/mikroe_nfctag2_nt3h2111) |
+| pwm_driver_si8711cc | [Click Here](./driver/public/mikroe/pwm_driver_si8711cc) | [Click Here](./app/example/mikroe_pwm_driver_si8711cc) | [Click Here](./app/documentation/example/mikroe_pwm_driver_si8711cc) |
## Requirements ##
@@ -113,4 +129,4 @@ The Third Party Hardware Drivers SDK contains the following files and folders.
To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of this repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
-Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of this repo.
\ No newline at end of file
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of this repo.
diff --git a/app/documentation/example/mikroe_e_paper_154_inch/README.md b/app/documentation/example/mikroe_e_paper_154_inch/README.md
new file mode 100644
index 00000000..aff6b2ce
--- /dev/null
+++ b/app/documentation/example/mikroe_e_paper_154_inch/README.md
@@ -0,0 +1,74 @@
+# E-Paper Display 1,54" 200x200 dots #
+
+## Summary ##
+
+This project aims to show the hardware driver that is used to interface with the E-Paper display 1,54" 200x200 dots driver from Mikroe via APIs of GSDK.
+
+E-Paper display is based on Active Matrix Electrophoretic Display (AMEPD) technology and has an integrated pixel driver, which uses the SPI interface to communicate with the host MCU. E-Paper display has resolution of 200(V) X 200(H) pixels and an active display area of 27.6 X 27.6. The size of its square shaped pixels is 0.138mm x 0.138mm. The screen displays a clear and crisp graphics, and has an ultra-wide viewing range. Another key feature of the E-Ink technology is the extremely low power consumption, even when the display actively refresh its content.
+
+## Required Hardware ##
+
+- [EFR32xG24 Explorer Kit](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview)
+
+- [EINK CLICK - WITHOUT DISPLAY](https://www.mikroe.com/eink-click-without-display)
+
+- [E-Paper display 1,54" 200x200 dots](https://www.mikroe.com/e-paper-display-154-200x200-dots)
+
+## Hardware Connection ##
+
+eINK display needs an external adapter to interface with the EFR32xG24 Explorer Kit. The hardware connection is shown in the image below:
+
+![board](image/hardware_connection.png)
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD2703A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with filter **E-Paper**.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - E-Paper Display (Mikroe)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "EFR32xG24 Explorer Kit" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file [app.c](https://github.com/SiliconLabs/third_party_hw_drivers_extension/tree/master/app/example/mikroe_e_paper) (overwriting the existing file) into the project root folder.
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - **[Services] → [IO Stream] → [IO Stream: USART]** → default instance name: vcom
+ - **[Third Party Hardware Drivers] → [Display & LED] → [E-Paper Display (Mikroe)]**
+ - **[Third Party Hardware Drivers] → [Services] → [GLIB - OLED Graphics Library]**
+
+4. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure that the Third-party drivers extension has already been installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+- Third-party drivers extension must be enabled for the project to install "E-Paper Display (Mikroe)" component. Selecting this component will also include the "SPIDRV" component with the default configurated instance: Mikroe.
+
+## How It Works ##
+
+### Testing ###
+
+After setting up all the required components, flash the code to the Explorer Kit and you will see the result looks like below.
+
+![result](image/result.png)
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/mikroe_e_paper_154_inch/image/create_example.png b/app/documentation/example/mikroe_e_paper_154_inch/image/create_example.png
new file mode 100644
index 00000000..23052624
Binary files /dev/null and b/app/documentation/example/mikroe_e_paper_154_inch/image/create_example.png differ
diff --git a/app/documentation/example/mikroe_e_paper_154_inch/image/hardware_connection.png b/app/documentation/example/mikroe_e_paper_154_inch/image/hardware_connection.png
new file mode 100644
index 00000000..9eb97644
Binary files /dev/null and b/app/documentation/example/mikroe_e_paper_154_inch/image/hardware_connection.png differ
diff --git a/app/documentation/example/mikroe_e_paper_154_inch/image/result.png b/app/documentation/example/mikroe_e_paper_154_inch/image/result.png
new file mode 100644
index 00000000..20c03ce5
Binary files /dev/null and b/app/documentation/example/mikroe_e_paper_154_inch/image/result.png differ
diff --git a/app/documentation/example/mikroe_lte_iot2_bg96/README.md b/app/documentation/example/mikroe_lte_iot2_bg96/README.md
new file mode 100644
index 00000000..76667b7f
--- /dev/null
+++ b/app/documentation/example/mikroe_lte_iot2_bg96/README.md
@@ -0,0 +1,275 @@
+# LTE IoT 2 Click #
+
+## Summary ##
+
+This project shows the implementation of an LTE IoT 2 Click driver using Quectel BG96 LTE module from Mikroe Integrated with EFR32xG24 Explorer Kit based on UART communication.
+LTE IoT 2 Click is a Click board™ that allows connection to the LTE networks, featuring Quectel BG96 LTE module, which offers two LTE technologies aimed at Machine to Machine communication (M2M) and the Internet of Things (IoT). This module is an embedded IoT communication solution that supports the LTE Cat M1 and NB1 technologies, offering an alternative to similar Low Power Wide Area Network (LPWAN) solutions, such as the ones provided by Sigfox and LoRa. The LTE CAT1 and NB1 technologies are designed with specific requirements of the IoT network in mind. LTE IoT 2 click also offers various other features, allowing simple and reliable connection to these new 3GPP IoT technologies.
+
+## Required Hardware ##
+
+- [**EFR32xG24-EK2703A** EFR32xG24 Explorer Kit (BRD2703A xG24 Explorer Kit Board)](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview).
+
+- [**LTE IoT 2 Click** board based on Quectel BG96 LTE module from Mikroe Integrated](https://www.mikroe.com/lte-iot-2-click).
+
+**NOTE:**
+Tested boards for working with this example:
+
+| Board ID | Description |
+| ---------------------- | ------ |
+| BRD2703A | [EFR32xG24 Explorer Kit - XG24-EK2703A ](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview) |
+| BRD4314A | [BGM220 Bluetooth Module Explorer Kit - BGM220-EK4314A](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit?tab=overview) |
+| BRD4108A | [EFR32BG22 Explorer Kit Board](https://www.silabs.com/development-tools/wireless/bluetooth/bg22-explorer-kit?tab=overview) |
+
+## Hardware Connection ##
+
+The LTE IoT 2 Click board can just be "clicked" into its place. Be sure that the board's 45-degree corner matches the Explorer Kit's 45-degree white line. The GSM antenna needs to be connected to the LTE IOT 2 Click board to ensure that the mobile network signal can be received. And also a SIM card is properly attached to the module. If the user using the GPS function then the GPS antenna needs to be connected to the LTE IoT 2 Click board to ensure that the satellite signals can be received.
+
+![board_1](image/hardware_connection_1.png "BRD2703A xG24 Explorer Kit Board and LTE IoT 2 Click Board")
+![board_2](image/hardware_connection_2.png "BRD2703A xG24 Explorer Kit Board and LTE IoT 2 Click Board")
+![board_3](image/hardware_connection_3.png "BRD2703A xG24 Explorer Kit Board and LTE IoT 2 Click Board")
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD2703A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with the filter 'lte iot 2'.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - BG96 - LTE IoT 2 CLick (Mikroe)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "EFR32xG24 Explorer Kit Explorer Kit Board" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file [app.c](https://github.com/SiliconLabs/third_party_hw_drivers_extension/tree/master/app/example/mikroe_lte_iot2_bg96) (overwriting existing file), [app_iostream_cli.c](https://github.com/SiliconLabs/third_party_hw_drivers_extension/tree/master/app/example/mikroe_lte_iot2_bg96) and [app_iostream_cli.h](https://github.com/SiliconLabs/third_party_hw_drivers_extension/tree/master/app/example/mikroe_lte_iot2_bg96) into the project root folder.
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - [Services] → [Sleep Timer]
+ - [Services] → [IO Stream] → [IO Stream: EUSART] → default instance name: vcom
+ - [Application] → [Utility] → [Log]
+ - [Application] → [Utility] → [Application Queue]
+ - [Third-Party Hardware Drivers] → [Sensors] → [BG96 - LTE IoT 2 Click (Mikroe)]
+
+4. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure the Third-party Hardware Drivers Extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+- Third-party Hardware Drivers Extension must be enabled for the project to install "BG96- LTE IoT 2 Click (Mikroe)" component.
+- The example project is built on the BRD2703A board. For other boards, selecting the "BG96 - LTE IoT 2 Click (Mikroe)" component will include the "UART" component with an unconfigured instance. This instance should be configurated by users.
+
+## How It Works ##
+
+- The Third Party Hardware Drivers - BG96 - LTE IoT 2 CLick (Mikroe) driver consists of three driver layers and an application layer on the top. The hardware peripheral configuration and low-level handling can be found on the lowest level.
+- The core driver schedules the sending of AT commands, maintains a command queue and handles the received responses. It also achieves an error handling that works similarly to exception handling in high-level programming languages. If any error occurs during the communication it can interrupt the command scheduler and report the appropriate error message to the high-level programming interface.
+- The high-level functions prepare the AT commands, extend them with parameters if necessary, put them into the command queue and start the scheduler. The basic functions like LTE network configuration, sending mobile sms, data send/receive on a TCP/IP socket and GPS positioning are already implemented but it is possible to write custom high-level functions too. You will find the detailed documentation in the code and a brief example of usage below.
+
+### BG96 - LTE IoT 2 Click general high-level functions ###
+
+- *bg96_init()*
+- *bg96_is_alive()*
+- *bg96_sleep()*
+- *bg96_wake_up()*
+
+### BG96 - LTE IoT 2 Click functional high-level functions ###
+
+- *bg96_nb_init(void)*
+- *bg96_nb_open_connection()*
+- *bg96_network_registration()*
+- *bg96_nb_close_connection()*
+- *bg96_nb_send_data()*
+- *bg96_nb_receive_data()*
+- *bg96_read_ip()*
+- *bg96_read_imei()*
+- *bg96_read_infor()*
+- *bg96_get_operator()*
+- *bg96_set_te_gsm()*
+- *bg96_config_service_domain()*
+- *bg96_set_sms_mode()*
+- *bg96_send_sms_text()*
+- *bg96_send_sms_pdu()*
+- *bg96_set_sim_apn()*
+- *bg96_gnss_start()*
+- *bg96_gnss_get_position()*
+- *bg96_gnss_stop()*
+
+## Driver Layer Overview ##
+
+![layer](image/layer.drawio.png)
+
+## Driver Extension Guide ##
+
+### Adding New AT Command ###
+
+To add new AT command to the parser you need to define an AT command line callback which depends on the required response of the command.
+The possible AT command responses are defined in the [User manual](https://docs.particle.io/assets/pdfs/Quectel_BG96_AT_Commands_Manual_V2.1.pdf) of the BG96 module. In some cases, one of the predefined line callbacks can be used. e.g.: *at_ok_error_cb()* if the command response is OK or ERROR.
+
+1. Define the appropriate line callback function in *at_parser_core.c*. You can find an example below.
+
+ ```c
+ void at_custom_cb(uint8_t *new_line, uint8_t call_number)
+ //call_number refers the number of new lines received as response
+ //new_line points to a string with the new line data
+ switch (call_number) {
+ case 1:
+ //the value of the new line can be parsed
+ if (has_substring(new_line, "OK")) {
+ //in case of the last response arrived scheduler can be stepped forward
+ at_parser_scheduler_next_cmd();
+ }
+ if (has_substring(new_line, "ERROR")) {
+ //data can be reported to the caller
+ at_parser_report_data(new_line);
+ //in case of error scheduler can be stopped and error code can be reported
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ //default case always SHALL be defined
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ ```
+
+2. Add the core process function to the main loop.
+
+ ```c
+ void app_process_action (void)
+ {
+ at_parser_process ();
+ ...
+ }
+ ```
+
+3. The definition of AT command SHALL be implemented in a high-level function. See the section **Creating New High Level Function**.
+
+### Creating New High Level Function ###
+
+Creating a high-level function means a single AT command or a list of AT commands which should be sent after each other to the BG96 IoT module and process their response, indicate errors and define the user data. The predefined high-level function can be found in *mikroe_bg96.c* files.
+
+ ```c
+ sl_status_t custom_high_level_function( user_data_t *custom_user_data, //you can use user data
+ at_scheduler_status_t *output_object) //you MUST define an output_object to receive the response
+ {
+ //define command status variable as SL_STATUS_OK, this will collect the errors of low level functions
+ sl_status_t cmd_status = SL_STATUS_OK;
+ //define the base and additional parts of the AT command, additional parts can be prameters inherited from user data
+ uint8_t extend_str[]= "0,0",
+ uint8_t base_cmd[] = "AT+QICLOSE=";
+
+ //create a STATIC command descriptor, this descriptor MUST be allocated during the AT command parsing process!
+ static at_cmd_desc_t at_custom = { .cms_string="", //use an empty cmd_string if there are additional parameters
+ .ln_cb=at_custom_cb, //add the appropriate line callback function
+ .timeout_ms = AT_DEFAULT_TIMEOUT //define a timeout for the command (check the BG96 datasheet for the decent timeout)
+ };
+ //prepare the command descriptor (clears the command string)
+ at_parser_clear_cmd(&at_custom);
+
+ //for the following functions use validate() function to indicate the errors!
+ //extend command descriptor command string with the base command
+ validate(cmd_status, at_parser_extend_cmd(&at_custom, base_cmd));
+ //extend command descriptor command string with the additional parts
+ validate(cmd_status, at_parser_extend_cmd(&at_custom, conn_string));
+ //add the command descriptor to the command queue, queue is available only if previous high level function finished
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_custom));
+ //start command scheduler, scheduler runs until the command queue is empty or error is occourred.
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+ ```
+
+### Creating New CLI Command ###
+
+1. Add a new element to the *cli_cmds[]* array in *app_iostream_cli.c*. The new element SHALL contain a CLI command string and a perform function. Use a short command and DO NOT use spaces and special characters! The maximum length of a CLI command is defined in *CLI_CMD_LENGTH* macro in *app_iostream_cli.h* and is 10 by default.
+
+ ```c
+ static cli_cmd_t cli_cmds[] = {
+ { "imei", imei },
+ { "ip", ip },
+ //you can define new CLI commands here
+ {"custom_cmd", custom_cmd}
+ };
+ ```
+
+2. Define the CLI command to perform a function. This is the function defined in the new element of *cli_cmd[]* array. Use static keywords!
+
+ ```c
+ static void custom_cmd()
+ {
+ //prepare an output object for receiving data from a high level function
+ at_parser_init_output_object(&output_object);
+ //call a high level function
+ custom_high_level_function(&output_object);
+ //create an event listener for the output object and define the event handler function
+ at_listen_event(&output_object.status, //pointer to a variable to check
+ SL_STATUS_OK, //the state the status variable should be equal to
+ custom_cmd_handler, //event handler function
+ (void*) &output_object); //parameter of event handler function
+
+ //you can write a short log if command perform function has run. Do not forget the \r\n at the end of the message!
+ printf("Custom command has been performed!\r\n");
+ }
+ ```
+
+3. Define the event handler function you gave in the event listener parameter list.
+
+ ```c
+ static void custom_cmd_handler(void *handler_data)
+ {
+ //handler data is a pointer to the user data passed by the event listener
+ //at_scheduler_state is a good option to propagate because it contains the AT command response
+ at_scheduler_status_t *l_output = (at_scheduler_status_t*) handler_data;
+
+ //check the error code and handle it
+ if (l_output->error_code) {
+ printf("Error while running custom command %d\r\n", l_output->error_code);
+ } else {
+ //print the response data if it was reported by the AT command line callback
+ printf("Custom command response: %s\r\n", l_output->response_data);
+ }
+ }
+ ```
+
+4. Add the event listener and IOstream process functions to the main loop.
+
+ ```c
+ void app_process_action (void)
+ {
+ app_iostream_usart_process_action ();
+ at_event_process ();
+ ...
+ }
+ ```
+
+### Testing ###
+
+- You can launch Console that's integrated into Simplicity Studio or use a third-party terminal tool like Tera Term to receive the data from the USB. In this example, we build a simple command line interface application. There are commonly used commands predefined in the "app_iostream_cli.c" file. When the user wants to test a feature, just call the corresponding commands.
+- First, after the chip has finished booting, the user needs to start the LTE IoT 2 module. Enter the command "wakeup" into Tera Term and end with an "Enter" key. A logline is printed confirming the command has been executed. The lower layer library will control the GPIO pin connected to the PWK pin to power the LTE IoT 2 module. After a few seconds the module boots up, and it will respond with a successful boot confirmation.
+- After the LTE IoT 2 module boots up successfully, users can check basic parameters such as getting imei code, and getting revision by "imei", "infor" commands. The user then calls the "service" command to configure the service domain type CS and PS. Next, the user calls the command "gsm" to select TE character set to GSM.
+- In this example, we send a text message from LTE IoT 2 Click module to a given phone number. There are two operating modes "textmode" and "pdumode" need to call these 2 commands first to put the module into operation mode respectively. The user can then invoke the "smstext" and "smspdu" commands to send the message. After confirming the successful message delivery, there will be a response, which contains the reference information of that sms.
+- In addition, we also provide an example using the GPS function. First, users need to turn on the GPS module with the "gpsstart" command. After the LTE IoT 2 Click module captures the satellite signal, the user can get the location coordinates with the "location" command. After getting the results, users can use the longitude and latitude values entered into Google Maps to check the actual location. In addition, the command also returns information such as UTC, altitude, date, etc. After use, the user can turn off the GPS function with the command "gpsstop", this is to save energy for the system.
+- A screenshot of the console output is shown in the figure below:
+
+ ![usb_debug](image/log.png "USB Debug Output Data")
+
+ ![usb_debug_gps](image/gps_log.png "USB Debug Output Data GPS")
+
+ ![sms_img](image/sms_receive.png "SMS Receive")
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/mikroe_lte_iot2_bg96/image/create_example.png b/app/documentation/example/mikroe_lte_iot2_bg96/image/create_example.png
new file mode 100644
index 00000000..9a710716
Binary files /dev/null and b/app/documentation/example/mikroe_lte_iot2_bg96/image/create_example.png differ
diff --git a/app/documentation/example/mikroe_lte_iot2_bg96/image/gps_log.png b/app/documentation/example/mikroe_lte_iot2_bg96/image/gps_log.png
new file mode 100644
index 00000000..10e414bf
Binary files /dev/null and b/app/documentation/example/mikroe_lte_iot2_bg96/image/gps_log.png differ
diff --git a/app/documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_1.png b/app/documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_1.png
new file mode 100644
index 00000000..83c67c73
Binary files /dev/null and b/app/documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_1.png differ
diff --git a/app/documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_2.png b/app/documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_2.png
new file mode 100644
index 00000000..999cdbe6
Binary files /dev/null and b/app/documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_2.png differ
diff --git a/app/documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_3.png b/app/documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_3.png
new file mode 100644
index 00000000..5e74637d
Binary files /dev/null and b/app/documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_3.png differ
diff --git a/app/documentation/example/mikroe_lte_iot2_bg96/image/layer.drawio.png b/app/documentation/example/mikroe_lte_iot2_bg96/image/layer.drawio.png
new file mode 100644
index 00000000..bc8f0122
Binary files /dev/null and b/app/documentation/example/mikroe_lte_iot2_bg96/image/layer.drawio.png differ
diff --git a/app/documentation/example/mikroe_lte_iot2_bg96/image/log.png b/app/documentation/example/mikroe_lte_iot2_bg96/image/log.png
new file mode 100644
index 00000000..054c88d7
Binary files /dev/null and b/app/documentation/example/mikroe_lte_iot2_bg96/image/log.png differ
diff --git a/app/documentation/example/mikroe_lte_iot2_bg96/image/sms_receive.png b/app/documentation/example/mikroe_lte_iot2_bg96/image/sms_receive.png
new file mode 100644
index 00000000..49c07d8e
Binary files /dev/null and b/app/documentation/example/mikroe_lte_iot2_bg96/image/sms_receive.png differ
diff --git a/app/documentation/example/mikroe_microsd/README.md b/app/documentation/example/mikroe_microsd/README.md
new file mode 100644
index 00000000..7a251acf
--- /dev/null
+++ b/app/documentation/example/mikroe_microsd/README.md
@@ -0,0 +1,126 @@
+# External Storage - microSD Click #
+
+## Summary ##
+
+This project aims to implement a hardware driver interacting with an SD Card using the microSD Click board. SD Cards support SDIO or SPI interfaces to communicate; this driver communicates via the SPI interface as SPI is widely available in embedded devices/micro-controllers.
+
+This project integrates FatFS which is one of the most popular file system libraries. File system related abstraction is handled by FatFS, and lower-level functions like the media IO layer are provided by this project's source code. For more information about FatFS, see the following [source](http://elm-chan.org/fsw/ff/doc/appnote.html).
+
+The microSD Click communicates with the target microcontroller over SPI interface that corresponds to the pinout on the mikroBUS™ socket as shown below.
+
+![mikroBus](images/mikrobus.png)
+
+## Required Hardware ##
+
+- [BGM220 Bluetooth Module Explorer Kit - BGM220-EK4314A](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit?tab=overview)
+
+- [A microSD Click board](https://www.mikroe.com/microsd-click)
+
+- A microSD card, e.g. [microSD card 32 GB with adapter](https://www.mikroe.com/microsd-32gb)
+
+**NOTE:**
+Tested boards for working with this example:
+
+| Board ID | Description |
+| ---------------------- | ------ |
+| BRD2703A | [EFR32xG24 Explorer Kit - XG24-EK2703A](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview) |
+| BRD4108A | [BG22 Bluetooth SoC Explorer Kit - BG22-EK4108A](https://www.silabs.com/development-tools/wireless/bluetooth/bg22-explorer-kit?tab=overview) |
+| BRD4314A | [BGM220 Bluetooth Module Explorer Kit - BGM220-EK4314A](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit?tab=overview) |
+
+## Hardware Connection ##
+
+The microSD Click board can be easily clicked into its place. During the assembly, be sure that the 45-degree corner of the board fits the 45-degree white line of the Explorer Kit.
+
+![board](images/board.png)
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD4314A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with filter microsd.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - microSD Click (Mikroe)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![create_example](images/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create a "Platform - Empty C Project" project for the "BGM220 Bluetooth Module Explorer Kit - BGM220-EK4314A" using Simplicity Studio v5. Use the default project settings. Be sure to connect and select the BGM220 Bluetooth Module Explorer Kit - BGM220-EK4314A Board from the "Debug Adapters" on the left before creating a project.
+
+2. Copy the files from app/example/mikroe_microsd folder into the project root folder (overwriting existing app.c).
+
+3. Install the software components:
+
+ - Open the .slcp file in the project
+
+ - Select the *SOFTWARE COMPONENTS* tab
+
+ - Install the following components:
+
+ - **[Third Party Hardware Drivers] → [Storage] → microSD - microSD Click (Mikroe)**
+ - **[Third Party Hardware Drivers] → [Storage] → FatFS - Generic FAT Filesystem**
+ - **[Services] → [IO Stream] → [IO Stream: USART]** with the default instance name: **vcom**
+
+ - **[Application] → [Utility] → [Log]**
+ - **[Application] → [Utility] → [Assert]**
+
+4. Build and flash the project to your device.
+
+**Note:**
+
+- Make sure the SDK extension already be installed. If not, please follow [this documentation](https://github.com/SiliconLabs/platform_hardware_drivers_sdk_extensions/blob/master/README.md).
+
+- SDK Extension must be enabled for the project to install "microSD - microSD Click (Mikroe)" component. Selecting this component will also include the "SPIDRV" component with default configurated instance: mikroe.
+
+- The example project are built on the BRD4314A board. For another boards, selecting the "microSD - microSD Click (Mikroe)" component will include the "SPIDRV" component with unconfigured instance: inst0. This instance should be configurated by users.
+
+## How It Works ##
+
+### API Overview ###
+
+The driver is divided into a FatFs, a Media access interface, and an SPI platform. The FatFs layer is the Filesystem Layer independent of platforms and storage media, it is completely separated from the physical device, such as memory card, hard disk, or any type of storage device. The media access interface is not part of the FatFs module and it needs to be provided by the implementer. FatFs controls the storage devices via a media access interface. The SPI platform layer provides integration to the host microcontroller hardware-dependent code.
+
+![system_oveview](images/system_overview.png)
+
+The dependency diagram is shown below.
+
+![structure_overview](images/structure_overview.png)
+
+**FatFS**: provides various filesystem functions for the applications.
+
+- File Access
+- Directory Access
+- File and Directory Management
+- Volume Management and System Configuration
+
+For more information about the APIs of the FatFS module, see the following [source](http://elm-chan.org/fsw/ff/00index_e.html).
+
+**Storage Device Controls Generic Media**: implements the generic media access interface by consuming device-specific storage device control implementations.
+**Storage Device Controls SD Card**: implements the storage device control interfaces specific to SD Card.
+
+**Storage Device Controls SD Card Platform**: implements basic interfaces required by the upper Storage Device Control layer. It implements SPI **byte, multibyte, exchange**, and other required functions by consuming platform SPI interfaces. The SPI instance is configurable via a public interface. SPI instance should be provided by passing as a parameter of the sd_card_spi_init() function.
+
+**Silicon Labs Platform**: implements the peripheral driver core.
+
+### Testing ###
+
+This example demonstrates the basic features of the driver as shown below:
+
+![Flow](images/workflow.png)
+
+Use a terminal program, such as the Console that is integrated into Simplicity Studio or a third-party tool terminal like Tera Term to receive the logs from the virtual COM port. You should expect a similar output to the one below.
+
+![testing_format](images/testing.png)
+
+Unmount the SD Card. Use a micro Card Reader to read files from the SD Card on your computer. You should expect a similar output to the one below.
+
+![content_file](images/content_file.png)
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/mikroe_microsd/images/board.png b/app/documentation/example/mikroe_microsd/images/board.png
new file mode 100644
index 00000000..988a14fd
Binary files /dev/null and b/app/documentation/example/mikroe_microsd/images/board.png differ
diff --git a/app/documentation/example/mikroe_microsd/images/content_file.png b/app/documentation/example/mikroe_microsd/images/content_file.png
new file mode 100644
index 00000000..1a1ebb0f
Binary files /dev/null and b/app/documentation/example/mikroe_microsd/images/content_file.png differ
diff --git a/app/documentation/example/mikroe_microsd/images/create_example.png b/app/documentation/example/mikroe_microsd/images/create_example.png
new file mode 100644
index 00000000..f0720fe3
Binary files /dev/null and b/app/documentation/example/mikroe_microsd/images/create_example.png differ
diff --git a/app/documentation/example/mikroe_microsd/images/mikrobus.png b/app/documentation/example/mikroe_microsd/images/mikrobus.png
new file mode 100644
index 00000000..23826410
Binary files /dev/null and b/app/documentation/example/mikroe_microsd/images/mikrobus.png differ
diff --git a/app/documentation/example/mikroe_microsd/images/structure_overview.png b/app/documentation/example/mikroe_microsd/images/structure_overview.png
new file mode 100644
index 00000000..d73ffec4
Binary files /dev/null and b/app/documentation/example/mikroe_microsd/images/structure_overview.png differ
diff --git a/app/documentation/example/mikroe_microsd/images/system_overview.png b/app/documentation/example/mikroe_microsd/images/system_overview.png
new file mode 100644
index 00000000..80f852ff
Binary files /dev/null and b/app/documentation/example/mikroe_microsd/images/system_overview.png differ
diff --git a/app/documentation/example/mikroe_microsd/images/testing.png b/app/documentation/example/mikroe_microsd/images/testing.png
new file mode 100644
index 00000000..293d9abe
Binary files /dev/null and b/app/documentation/example/mikroe_microsd/images/testing.png differ
diff --git a/app/documentation/example/mikroe_microsd/images/workflow.png b/app/documentation/example/mikroe_microsd/images/workflow.png
new file mode 100644
index 00000000..a32cbd89
Binary files /dev/null and b/app/documentation/example/mikroe_microsd/images/workflow.png differ
diff --git a/app/documentation/example/mikroe_nfc2_pn7150/README.md b/app/documentation/example/mikroe_nfc2_pn7150/README.md
new file mode 100644
index 00000000..d44d1e05
--- /dev/null
+++ b/app/documentation/example/mikroe_nfc2_pn7150/README.md
@@ -0,0 +1,85 @@
+# PN7150 - NFC 2 Click #
+
+## Summary ##
+
+This example demonstrates the usage of NFC 2 Click board with BGM220P Explorer Kit based on I2C communication.
+
+NFC 2 Click is based on the PN7150, high-performance full NFC solution with integrated firmware and I2C interface designed for contactless communication at 13.56 MHz from NXP.
+
+NFC 2 Click board can be used for the detection of NFC Tag and can be used for rapidly integrating NFC technology in any application.
+
+## Required Hardware ##
+
+- [A BGM220P Explorer Kit board](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit)
+
+- [An NFC 2 Click](https://www.mikroe.com/nfc-2-click)
+
+- A T2T tag
+
+## Hardware Connection ##
+
+The NFC 2 Click board can just be "clicked" into its place. Be sure that the board's 45-degree corner matches the Explorer Kit's 45-degree white line.
+
+![board](image/hardware_connection.png)
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD4314A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with the filter: *nfc 2*.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - PN7150 - NFC 2 Click (Mikroe) - I2C** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "BGM220 Explorer Kit Board" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file app/example/mikroe_nfc2_pn7150/app.c into the project root folder (overwriting existing file).
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - [Services] → [IO Stream] → [IO Stream: USART] → default instance name: vcom
+ - [Application] → [Utility] → [Log]
+ - [Third Party Hardware Drivers] → [Wireless Connectivity] → [PN7150 - NFC 2 Click (Mikroe) - I2C] → use default configuration
+
+4. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure that the SDK extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+- Third-party Hardware Drivers Extension must be enabled for the project to install "PN7150 - NFC 2 Click (Mikroe) - I2C" component.
+
+## How It Works ##
+
+The application is composed of three sections :
+
+- Application Initialization: - Initialization driver enables - I2C,
+ hw reset, reset and initialize core, disabling standby mode,
+ starting test procedure, set configuration and start discovery, also write log.
+- Application process: NFC 2 Click board can be used for the detection of NFC tag and displays its value via USART terminal.
+
+## Testing ##
+
+After initialization, the application automatically looks for nearby compatible tags. Place a T2T tag near NFC 2 Click board. After detecting a tag, the application shows logs on the terminal.
+
+You can launch Console that's integrated into Simplicity Studio or use a third-party terminal tool like TeraTerm to receive the data from the USB. A screenshot of the console output is shown in the figure below.
+
+![usb_debug](image/log.png "USB Debug Output Data")
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/mikroe_nfc2_pn7150/image/create_example.png b/app/documentation/example/mikroe_nfc2_pn7150/image/create_example.png
new file mode 100644
index 00000000..96cee5d7
Binary files /dev/null and b/app/documentation/example/mikroe_nfc2_pn7150/image/create_example.png differ
diff --git a/app/documentation/example/mikroe_nfc2_pn7150/image/hardware_connection.png b/app/documentation/example/mikroe_nfc2_pn7150/image/hardware_connection.png
new file mode 100644
index 00000000..dea80cbe
Binary files /dev/null and b/app/documentation/example/mikroe_nfc2_pn7150/image/hardware_connection.png differ
diff --git a/app/documentation/example/mikroe_nfc2_pn7150/image/log.png b/app/documentation/example/mikroe_nfc2_pn7150/image/log.png
new file mode 100644
index 00000000..35f11a35
Binary files /dev/null and b/app/documentation/example/mikroe_nfc2_pn7150/image/log.png differ
diff --git a/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/README.md b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/README.md
new file mode 100644
index 00000000..c08f5c80
--- /dev/null
+++ b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/README.md
@@ -0,0 +1,78 @@
+# PN7150 - NFC 2 Click - Read a T2T Tag with NCI #
+
+## Summary ##
+
+This example project demonstrates the interface of the NFC NCI service by using the NFC controller PN7150 to read a T2T Tag.
+
+## Required Hardware ##
+
+- [A BGM220P Explorer Kit board](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit)
+
+- [An NFC 2 Click](https://www.mikroe.com/nfc-2-click)
+
+- A T2T tag (E.g. [NFC 2 Tag Click](https://www.mikroe.com/nfc-tag-2-click))
+
+## Hardware Connection ##
+
+The NFC 2 Click board can just be "clicked" into its place. Be sure that the board's 45-degree corner matches the Explorer Kit's 45-degree white line.
+
+![board](image/hardware_connection.png)
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD4314A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with the filter: *nci*.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - PN7150 - Read a T2T Tag with NCI** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "BGM220 Explorer Kit Board" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file app/example/mikroe_nfc2_pn7150_nci_t2t_read/app.c into the project root folder (overwriting existing file).
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - [Services] → [IO Stream] → [IO Stream: USART] → default instance name: vcom
+ - [Application] → [Utility] → [Log]
+ - [Application] → [Utility] → [Assert]
+ - [Platform] → [Driver] → [GPIOINT]
+ - [Services] → [Timers] → [Sleep Timer]
+ - [Third Party Hardware Drivers] → [Wireless Connectivity] → [PN7150 - NFC 2 Click (Mikroe) - I2C] → use default configuration
+ - [Third Party Hardware Drivers] → [Services] → [NFC] → [NFC - NCI] → use default configuration
+ - [Third Party Hardware Drivers] → [Services] → [NFC] → [NFC - Common]
+ - [Third Party Hardware Drivers] → [Services] → [NFC] → [NFC - Tag]
+
+4. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure that the SDK extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+- Third-party Hardware Drivers Extension must be enabled for the project to install any extension components.
+
+## How It Works ##
+
+After initialization, the application automatically looks for nearby compatible tags. Place a T2T tag near NFC 2 Click board. After detecting a tag, the application should dump the memory content to the serial terminal.
+
+You can launch Console that's integrated into Simplicity Studio or use a third-party terminal tool like TeraTerm to receive the data from the USB. A screenshot of the console output is shown in the figure below.
+
+![usb_debug](image/log.png "USB Debug Output Data")
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/create_example.png b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/create_example.png
new file mode 100644
index 00000000..50eae577
Binary files /dev/null and b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/create_example.png differ
diff --git a/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/hardware_connection.png b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/hardware_connection.png
new file mode 100644
index 00000000..eb868ea0
Binary files /dev/null and b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/hardware_connection.png differ
diff --git a/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/log.png b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/log.png
new file mode 100644
index 00000000..87ff7143
Binary files /dev/null and b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/log.png differ
diff --git a/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/README.md b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/README.md
new file mode 100644
index 00000000..a52be65e
--- /dev/null
+++ b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/README.md
@@ -0,0 +1,81 @@
+# PN7150 - NFC 2 Click - Write to a T2T Tag with NCI #
+
+## Summary ##
+
+This example project demonstrates the interface of the NFC NCI service by using the NFC controller PN7150 to write to a T2T Tag.
+
+## Required Hardware ##
+
+- [A BGM220P Explorer Kit board](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit)
+
+- [An NFC 2 Click](https://www.mikroe.com/nfc-2-click)
+
+- A T2T tag (E.g. [NFC 2 Tag Click](https://www.mikroe.com/nfc-tag-2-click))
+
+## Hardware Connection ##
+
+The NFC 2 Click board can just be "clicked" into its place. Be sure that the board's 45-degree corner matches the Explorer Kit's 45-degree white line.
+
+![board](image/hardware_connection.png)
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD4314A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with the filter: *nci*.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - PN7150 - Write to a T2T Tag with NCI** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "BGM220 Explorer Kit Board" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file app/example/mikroe_nfc2_pn7150_nci_t2t_write/app.c into the project root folder (overwriting existing file).
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - [Services] → [IO Stream] → [IO Stream: USART] → default instance name: vcom
+ - [Application] → [Utility] → [Log]
+ - [Application] → [Utility] → [Assert]
+ - [Platform] → [Driver] → [GPIOINT]
+ - [Services] → [Timers] → [Sleep Timer]
+ - [Third Party Hardware Drivers] → [Wireless Connectivity] → [PN7150 - NFC 2 Click (Mikroe) - I2C] → use default configuration
+ - [Third Party Hardware Drivers] → [Services] → [NFC] → [NFC - NCI] → use default configuration
+ - [Third Party Hardware Drivers] → [Services] → [NFC] → [NFC - Common]
+ - [Third Party Hardware Drivers] → [Services] → [NFC] → [NFC - Tag]
+ - [Third Party Hardware Drivers] → [Services] → [NFC] → [NFC - NDEF]
+
+4. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure that the SDK extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+- Third-party Hardware Drivers Extension must be enabled for the project to install any extension components.
+
+## How It Works ##
+
+After initialization, the application automatically looks for nearby compatible tags. Place a T2T tag near NFC 2 Click board. After detecting a tag, the application write an NFC message with a record that contains the following URL to a type 2 tag.
+
+`silabs.com/wireless/bluetooth`
+
+You can launch Console that's integrated into Simplicity Studio or use a third-party terminal tool like TeraTerm to receive the data from the USB. A screenshot of the console output is shown in the figure below.
+
+![usb_debug](image/log.png "USB Debug Output Data")
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/create_example.png b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/create_example.png
new file mode 100644
index 00000000..7594dab6
Binary files /dev/null and b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/create_example.png differ
diff --git a/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/hardware_connection.png b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/hardware_connection.png
new file mode 100644
index 00000000..95102343
Binary files /dev/null and b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/hardware_connection.png differ
diff --git a/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/log.png b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/log.png
new file mode 100644
index 00000000..2db5311c
Binary files /dev/null and b/app/documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/log.png differ
diff --git a/app/documentation/example/mikroe_nfctag2_nt3h2111/README.md b/app/documentation/example/mikroe_nfctag2_nt3h2111/README.md
new file mode 100644
index 00000000..58a22ce2
--- /dev/null
+++ b/app/documentation/example/mikroe_nfctag2_nt3h2111/README.md
@@ -0,0 +1,106 @@
+# NT3H2111 - NFC Tag 2 Click #
+
+## Summary ##
+
+This project shows the implementation of an NFC Tag module that carries the NT3H2111 from NXP.
+
+NT3H2111 is an NFC Forum Type 2 Tag (T2T) compliant tag IC with an I2C interface to an MCU host. It is perfectly suited for NFC applications that require energy harvesting NFC Forum Type 2 Tag.
+
+## Required Hardware ##
+
+- [A BGM220P Explorer Kit board](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit)
+
+- [An NFC Tag 2 Click](https://www.mikroe.com/nfc-tag-2-click)
+
+## Hardware Connection ##
+
+The Accel 5 Click board can just be "clicked" into its place. Be sure that the board's 45-degree corner matches the Explorer Kit's 45-degree white line.
+
+![board](image/hardware_connection.png)
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD4314A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with the filter: *nfc tag*.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - NT3H2111 - NFC Tag 2 Click (Mikroe) - I2C** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "BGM220 Explorer Kit Board" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file app/example/mikroe_nfctag2_nt3h2111/app.c into the project root folder (overwriting existing file).
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - [Services] → [IO Stream] → [IO Stream: USART] → default instance name: vcom
+ - [Application] → [Utility] → [Log]
+ - [Third Party Hardware Drivers] → [Wireless Connectivity] → [NT3H2111 - NFC Tag 2 Click (Mikroe) - I2C] → use default configuration
+
+4. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure that the SDK extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+- Third-party Hardware Drivers Extension must be enabled for the project to install "NT3H2111 - NFC Tag 2 Click (Mikroe) - I2C" component.
+
+## How It Works ##
+
+### API Overview ###
+
+```txt
+ ---------------------------------------------
+| Application |
+|---------------------------------------------|
+| mikroe_nt3h2111.c |
+|---------------------------------------------|
+| mikroe_nt3h2111_i2c.c |
+|---------------------------------------------|
+| emlib |
+ ---------------------------------------------
+```
+
+`mikroe_nt3h2111.c`: implements the top-level APIs for application.
+
+- Initialization API: Initialize I2C communication and FD interrupt.
+- memory block R/W APIs: read/write a memory block, given memory address.
+- specific register read/write APIs: specific register read/write to get and set settings for NT3H2x11.
+
+`mikroe_nt3h2111_i2c.c`: implements NT3H2x11 specific I2C APIs, called by `mikroe_nt3h2111.c`.
+
+- Initialization API: initialize I2C communication.
+- I2C read/write APIs: read/write a memory block via I2C, given memory address.
+- I2C read/write register APIs: read/write a register via I2C, given block memory address and register address.
+
+### Testing ###
+
+Application would first call `nt3h2111_init` to initialize needed peripherals(I2C, GPIO FD). Then use register read/write APIs to adjust the settings on the NT3H2111. The example will call any function based on the character it receives over the serial connection.
+
+You can launch Console that's integrated into Simplicity Studio or use a third-party terminal tool like TeraTerm to receive the data from the USB. A screenshot of the console output is shown in the figure below.
+
+![usb_debug](image/log.png "USB Debug Output Data")
+
+**Note**: After an NDEF message is written into NT3H2111 EEPROM, you can either use an NFC-enabled smartphone or use an RFID-reader module to read the data it contains.
+
+A screenshot of an NFC-enabled smartphone that uses the *NFC Tools* application to read data from NT3H2111 as shown below.
+
+![nfc tools](image/nfc_tools.png "USB Debug Output Data")
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/mikroe_nfctag2_nt3h2111/image/create_example.png b/app/documentation/example/mikroe_nfctag2_nt3h2111/image/create_example.png
new file mode 100644
index 00000000..71c7b299
Binary files /dev/null and b/app/documentation/example/mikroe_nfctag2_nt3h2111/image/create_example.png differ
diff --git a/app/documentation/example/mikroe_nfctag2_nt3h2111/image/hardware_connection.png b/app/documentation/example/mikroe_nfctag2_nt3h2111/image/hardware_connection.png
new file mode 100644
index 00000000..bd2a44fa
Binary files /dev/null and b/app/documentation/example/mikroe_nfctag2_nt3h2111/image/hardware_connection.png differ
diff --git a/app/documentation/example/mikroe_nfctag2_nt3h2111/image/log.png b/app/documentation/example/mikroe_nfctag2_nt3h2111/image/log.png
new file mode 100644
index 00000000..7c1e39aa
Binary files /dev/null and b/app/documentation/example/mikroe_nfctag2_nt3h2111/image/log.png differ
diff --git a/app/documentation/example/mikroe_nfctag2_nt3h2111/image/nfc_tools.png b/app/documentation/example/mikroe_nfctag2_nt3h2111/image/nfc_tools.png
new file mode 100644
index 00000000..0cb240fb
Binary files /dev/null and b/app/documentation/example/mikroe_nfctag2_nt3h2111/image/nfc_tools.png differ
diff --git a/app/documentation/example/mikroe_oledc_ssd1351/README.md b/app/documentation/example/mikroe_oledc_ssd1351/README.md
new file mode 100644
index 00000000..3fd64cfd
--- /dev/null
+++ b/app/documentation/example/mikroe_oledc_ssd1351/README.md
@@ -0,0 +1,86 @@
+# OLED C Click #
+
+## Summary ##
+
+This project shows the driver implementation of a SPI OLED using the SSD1351 IC with Silicon Labs Platform.
+
+OLED C click is equipped with the 96x96 high-color OLED display. It can display up to 65K/262K different colors and shades on a compact size display, based on the OLED technology. The OLED technology provides a very good brightness-to-contrast ratio, doesn’t require any backlight - since the pixel elements emit light on their own, better angle of viewing - compared to traditional TFT screens, better power consumption, better picture quality, better response times and more. The OLED technology is constantly being perfected and it is slowly taking over the existing liquid crystal technology (TFT).
+
+## Required Hardware ##
+
+**Silabs Development Kits**
+
+- [EFR32xG24 Explorer Kit - XG24-EK2703A](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview)
+
+**External Hardware**
+
+- [OLED C Click](https://www.mikroe.com/oled-c-click)
+
+**NOTE:**
+Tested boards for working with this example:
+
+| Board ID | Description |
+| ---------------------- | ------ |
+| BRD2703A | [EFR32xG24 Explorer Kit - XG24-EK2703A ](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview) |
+| BRD4314A | [BGM220 Bluetooth Module Explorer Kit - BGM220-EK4314A](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit?tab=overview) |
+| BRD4108A | [EFR32BG22 Explorer Kit Board](https://www.silabs.com/development-tools/wireless/bluetooth/bg22-explorer-kit?tab=overview) |
+
+## Hardware Connection ##
+
+The OLEDC Click board support MikroBus, so it can connect easily to EFR32xG24 Explorer Kit MikroBus header. Be sure that the board's 45-degree corner matches the Explorer Kit's 45-degree white line.
+
+The hardware connection is shown in the image below:
+
+![board](image/hardware_connection.png "Hardware connection")
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD2703A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with filter *oledc*.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - SSD1351 - OLED C Click Board (Mikroe)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+
+![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "EFR32xG24 Explorer Kit" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file /app/example/mikroe_oledc_ssd1351/app.c (overwriting existing file), into the project root folder.
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - [Services] → [Simple Timer]
+ - [Services] → [IO Stream] → [IO Stream: USART] → default instance name: vcom
+ - [Application] → [Utility] → [Assert]
+ - [Third Party Hardware Drivers] → [Display & LED] → [SSD1351 - OLED C Click (Mikroe) - SPI]
+ - [Third Party Hardware Drivers] → [Services] → [GLIB - OLED Graphics Library]
+4. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure the SDK extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+## How It Works ##
+
+The OLED display will look something like the GIF below.
+
+![test](image/test.gif)
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
+
diff --git a/app/documentation/example/mikroe_oledc_ssd1351/image/create_example.png b/app/documentation/example/mikroe_oledc_ssd1351/image/create_example.png
new file mode 100644
index 00000000..bbe4cd6b
Binary files /dev/null and b/app/documentation/example/mikroe_oledc_ssd1351/image/create_example.png differ
diff --git a/app/documentation/example/mikroe_oledc_ssd1351/image/hardware_connection.png b/app/documentation/example/mikroe_oledc_ssd1351/image/hardware_connection.png
new file mode 100644
index 00000000..ef5fc378
Binary files /dev/null and b/app/documentation/example/mikroe_oledc_ssd1351/image/hardware_connection.png differ
diff --git a/app/documentation/example/mikroe_oledc_ssd1351/image/test.gif b/app/documentation/example/mikroe_oledc_ssd1351/image/test.gif
new file mode 100644
index 00000000..da6b1ab7
Binary files /dev/null and b/app/documentation/example/mikroe_oledc_ssd1351/image/test.gif differ
diff --git a/app/documentation/example/mikroe_pressure3_dps310/README.md b/app/documentation/example/mikroe_pressure3_dps310/README.md
new file mode 100644
index 00000000..9bc3f281
--- /dev/null
+++ b/app/documentation/example/mikroe_pressure3_dps310/README.md
@@ -0,0 +1,95 @@
+# Pressure 3 Click #
+
+## Summary ##
+
+This project shows the implementation of barometer-sensor driver using Pressure 3 click (DPS310) from Mikroe Integrated with BGM220 Explorer Kit.
+
+## Required Hardware ##
+
+- [**BRD4314A-BGM220** BGM220 Bluetooth Module Explorer Kit (BRD4314A-BGM220 Explorer Kit Board)](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit?tab=overview)
+
+- [**Pressure 3 Click** board based on DPS310 from Mikroe Integrated](https://www.mikroe.com/pressure-3-click).
+
+**NOTE:**
+Tested boards for working with this example:
+
+| Board ID | Description |
+| ---------------------- | ------ |
+| BRD2703A | [EFR32xG24 Explorer Kit - XG24-EK2703A ](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview) |
+| BRD4314A | [BGM220 Bluetooth Module Explorer Kit - BGM220-EK4314A](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit?tab=overview) |
+| BRD4108A | [EFR32BG22 Explorer Kit Board](https://www.silabs.com/development-tools/wireless/bluetooth/bg22-explorer-kit?tab=overview) |
+
+## Hardware Connection ##
+
+The Pressure 3 Click board can just be "clicked" into its place. Be sure that the board's 45-degree corner matches the Explorer Kit's 45-degree white line.
+
+The hardware connection is shown in the image below:
+
+![board](image/hardware_connection.png "BGM220 Explorer Kit Board and Pressure 3 Click Board")
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD2703A to MyProducts, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with filter 'pressure'.
+
+2. Click **Create** button on the example:
+
+ - **Third Party Hardware Drivers - DPS310 - Pressure 3 click (Mikroe) - I2C** if using the I2C interface.
+
+ - **Third Party Hardware Drivers - DPS310 - Pressure 3 click (Mikroe) - SPI** if using the SPI interface.
+
+ Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+ ![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "BGM220 Explorer Kit Board" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file app/example/mikroe_pressure3_dps310/app.c into the project root folder (overwriting existing file).
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - [Services] → [Sleep Timer]
+ - [Services] → [IO Stream] → [IO Stream: USART] → default instance name: vcom
+ - [Application] → [Utility] → [Log]
+ - If using the SPI interface:
+ - [Third Party Hardware Drivers] → [Sensors] → [DPS310 - Mikroe Pressure 3 Click (SPI)]
+ - [Platform] → [Driver] → [SPI] → [SPIDRV] → [mikroe]: change the configuration for [SPI master chip select (CS) control scheme] to "CS controlled by the application"
+ - If using the I2C interface: [Third Party Hardware Drivers] → [Sensors] → [DPS310 - Mikroe Pressure 3 Click (I2C)]
+
+4. Install printf float
+
+ - Open Properties of the project.
+
+ - Select C/C++ Build → Settings → Tool Settings → GNU ARM C Linker → General. Check Printf float.
+
+ ![float](image/float.png)
+
+5. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure the SDK extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+## How It Works ##
+
+You can launch Console that's integrated into Simplicity Studio or use a third-party terminal tool like TeraTerm to receive the data from the USB. A screenshot of the console output is shown as the figure below.
+
+![usb_debug](image/log.png "USB Debug Output Data")
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/mikroe_pressure3_dps310/image/create_example.png b/app/documentation/example/mikroe_pressure3_dps310/image/create_example.png
new file mode 100644
index 00000000..e0b8859c
Binary files /dev/null and b/app/documentation/example/mikroe_pressure3_dps310/image/create_example.png differ
diff --git a/app/documentation/example/mikroe_pressure3_dps310/image/float.png b/app/documentation/example/mikroe_pressure3_dps310/image/float.png
new file mode 100644
index 00000000..e6b6e9c1
Binary files /dev/null and b/app/documentation/example/mikroe_pressure3_dps310/image/float.png differ
diff --git a/app/documentation/example/mikroe_pressure3_dps310/image/hardware_connection.png b/app/documentation/example/mikroe_pressure3_dps310/image/hardware_connection.png
new file mode 100644
index 00000000..bbad584c
Binary files /dev/null and b/app/documentation/example/mikroe_pressure3_dps310/image/hardware_connection.png differ
diff --git a/app/documentation/example/mikroe_pressure3_dps310/image/log.png b/app/documentation/example/mikroe_pressure3_dps310/image/log.png
new file mode 100644
index 00000000..83563017
Binary files /dev/null and b/app/documentation/example/mikroe_pressure3_dps310/image/log.png differ
diff --git a/app/documentation/example/mikroe_pwm_driver_si8711cc/README.md b/app/documentation/example/mikroe_pwm_driver_si8711cc/README.md
new file mode 100644
index 00000000..0a5772af
--- /dev/null
+++ b/app/documentation/example/mikroe_pwm_driver_si8711cc/README.md
@@ -0,0 +1,93 @@
+# PWM Driver Click #
+
+## Summary ##
+
+This project shows the implementation of an "PWM Driver Click" driver using Si8711CC one-channel isolator from Silicon Lab with EFR32xG24 Explorer Kit.
+
+If you need to control DC motors with loads up to 10A, PWM driver click is the perfect solution, thanks to the Silicon Lab Si8711CC one-channel isolator. It communicates with the target MCU over PWM pin, and runs on a 5V power supply. It can be used in a wide variety of ways, from controlling light intensity to serving as an ON/OFF switch to control DC load circuits.
+
+The Si87xx isolators are pin-compatible, one-channel, drop-in replacements for popular optocouplers with data rates up to 15 Mbps. These devices isolate highspeed digital signals and offer performance, reliability, and flexibility advantages not available with optocoupler solutions. The Si87xx series is based on proprietary CMOS isolation technology for low-power and high-speed operation and are resistant to the wear-out effects found in optocouplers that degrade performance with increasing temperature, forward current, and device age. As a result, the Si87xx series offer longer service life and dramatically higher reliability compared to optocouplers. Ordering options include open collector output with and without integrated pull-up resistor and output enable options.
+
+The click contains a P-channel DMP3010LK3 MOSFET transistor. When the click is used for PWM control it is not recommended to use it with loads of wattage over 50W because the MOSFET chip can get overheated. However, this does not apply when the click is used as an ON/OFF switch.
+
+## Required Hardware ##
+
+- [**EFR32xG24-EK2703A** EFR32xG24 Explorer Kit (BRD2703A xG24 Explorer Kit Board)](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview).
+
+- [**PWM Driver Click** board based on Si8711CC one-channel isolator from Silicon Lab](https://www.mikroe.com/pwm-driver-click).
+
+**NOTE:**
+Tested boards for working with this example:
+
+| Board ID | Description |
+| ---------------------- | ------ |
+| BRD2703A | [EFR32xG24 Explorer Kit - XG24-EK2703A ](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview) |
+| BRD4314A | [BGM220 Bluetooth Module Explorer Kit - BGM220-EK4314A](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit?tab=overview) |
+| BRD4108A | [BG22 Bluetooth SoC Explorer Kit](https://www.silabs.com/development-tools/wireless/bluetooth/bg22-explorer-kit?tab=overview) |
+
+## Hardware Connection ##
+
+The PWM Driver Click board can just be "clicked" into its place. Be sure that the board's 45-degree corner matches the Explorer Kit's 45-degree white line.
+
+![board_1](image/hardware_connection_1.png "BRD2703A xG24 Explorer Kit Board and PWM Driver Click Board")
+
+![board_2](image/hardware_connection_2.png "BRD2703A xG24 Explorer Kit Board and PWM Driver Click Board")
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD2703A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with the filter 'pwm driver'.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - SI8711CC - PWM Driver Click (Mikroe)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "EFR32xG24 Explorer Kit Explorer Kit Board" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file "app/example/mikroe_pwm_driver_si8711cc/app.c" into the project root folder (overwriting existing file).
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - [Services] → [Sleep Timer]
+ - [Services] → [IO Stream] → [IO Stream: USART] → default instance name: vcom
+ - [Application] → [Utility] → [Log]
+ - [Third-Party Hardware Drivers] → [Motor Control] → [Si8711CC - PWM Driver Click (Mikroe)]
+
+4. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure the Third-party Hardware Drivers Extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_Drivers_extension/blob/master/README.md).
+
+- Third-party Hardware Drivers Extension must be enabled for the project to install "Si8711CC - PWM Driver Click (Mikroe)" component.
+
+## How It Works ##
+
+- You can launch Console that's integrated into Simplicity Studio or use a third-party terminal tool like Tera Term to receive the data from the USB. In this example, we build a simple application that generate a PWM signal with frequency = 1000Hz, and duty level = 10% at startup. This duty level will be increased by 10% each 2000ms. If duty level >= 100% then duty level will be set to 10%.
+- A screenshot of the console output is shown in the figure below:
+
+ ![usb_debug](image/log.png "USB Debug Output Data")
+
+ ![result_2](image/result_2.png "Result_2")
+
+ ![result_3](image/result_3.png "Result_3")
+
+ ![result_1](image/result_1.png "Result_1")
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_Drivers_extension](https://github.com/SiliconLabs/third_party_hw_Drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_Drivers_extension](https://github.com/SiliconLabs/third_party_hw_Drivers_extension) repo.
diff --git a/app/documentation/example/mikroe_pwm_driver_si8711cc/image/create_example.png b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/create_example.png
new file mode 100644
index 00000000..3c4b2959
Binary files /dev/null and b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/create_example.png differ
diff --git a/app/documentation/example/mikroe_pwm_driver_si8711cc/image/hardware_connection_1.png b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/hardware_connection_1.png
new file mode 100644
index 00000000..287f7987
Binary files /dev/null and b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/hardware_connection_1.png differ
diff --git a/app/documentation/example/mikroe_pwm_driver_si8711cc/image/hardware_connection_2.png b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/hardware_connection_2.png
new file mode 100644
index 00000000..71d98895
Binary files /dev/null and b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/hardware_connection_2.png differ
diff --git a/app/documentation/example/mikroe_pwm_driver_si8711cc/image/log.png b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/log.png
new file mode 100644
index 00000000..800874f0
Binary files /dev/null and b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/log.png differ
diff --git a/app/documentation/example/mikroe_pwm_driver_si8711cc/image/result_1.png b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/result_1.png
new file mode 100644
index 00000000..27444e86
Binary files /dev/null and b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/result_1.png differ
diff --git a/app/documentation/example/mikroe_pwm_driver_si8711cc/image/result_2.png b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/result_2.png
new file mode 100644
index 00000000..687eb688
Binary files /dev/null and b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/result_2.png differ
diff --git a/app/documentation/example/mikroe_pwm_driver_si8711cc/image/result_3.png b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/result_3.png
new file mode 100644
index 00000000..fc68f3a3
Binary files /dev/null and b/app/documentation/example/mikroe_pwm_driver_si8711cc/image/result_3.png differ
diff --git a/app/documentation/example/mikroe_rf_meter_ad8318/README.md b/app/documentation/example/mikroe_rf_meter_ad8318/README.md
new file mode 100644
index 00000000..8d6144ec
--- /dev/null
+++ b/app/documentation/example/mikroe_rf_meter_ad8318/README.md
@@ -0,0 +1,100 @@
+# RF Meter Click #
+
+## Summary ##
+
+This example project shows an example for Mikroe RF Meter Click board driver integration with the Silicon Labs Platform.
+
+RF Meter Click is a compact add-on board that measures radio frequency power. It covers a frequency span from 1MHz up to 8GHz over a 60dB range, approximately. RF Meter Click is based on the AD8318, a logarithmic detector/controller from Analog Devices. It is a demodulating logarithmic amplifier capable of accurately converting an RF input signal to a corresponding decibel-scaled output voltage. The voltage output of the AD8318 goes to the MCP3201, a successive approximation 12-bit analog-to-digital converter with an onboard sample and holds circuitry from Microchip. The RF Meter uses a 3-wire SPI serial interface of the MCP3201 to communicate to the host MCU over the mikroBUS™ socket.
+
+This example can be used for testing equipment that includes RF transmitters or relays. It enables monitoring and measuring frequency levels to ensure proper functioning and leak detection.
+
+## Required Hardware ##
+
+- [**EFR32xG24-EK2703A** EFR32xG24 Explorer Kit](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview).
+
+- [**Mikroe RF Meter Click** board based on AD8318](https://www.mikroe.com/rf-meter-click-click).
+
+**NOTE:**
+Tested boards for working with this example:
+
+| Board ID | Description |
+| ---------------------- | ------ |
+| BRD2703A | [xG24-EK2703A - EFR32xG24 Explorer Kit ](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview) |
+| BRD4314A | [BGM220-EK4314A - BGM220 Bluetooth Module Explorer Kit](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit?tab=overview) |
+| BRD4108A | [BG22-EK4108A - EFR32BG22 Explorer Kit Board](https://www.silabs.com/development-tools/wireless/bluetooth/bg22-explorer-kit?tab=overview) |
+
+## Hardware Connection ##
+
+The RF Meter Click board supports MikroBus, so it can connect easily to EFR32xG24 Explorer Kit's MikroBus header. Be sure that the board's 45-degree corner matches the Explorer Kit's 45-degree white line.
+
+The hardware connection is shown in the image below:
+
+![hardware_connection](hardware_connection.png)
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD2703A to MyProducts, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with the filter **"rf meter"**.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - AD8318 - RF Meter Click (Mikroe)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![create_project](create_example.png)
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "EFR32xG24 Explorer Kit Board" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file [app.c](../../../example/mikroe_rf_meter_ad8318/app.c) (overwriting existing file), into the project root folder.
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - [Services] → [IO Stream] → [IO Stream: EUSART] → default instance name: **vcom**
+
+ - [Application] → [Utility] → [Log]
+
+ - [Application] → [Service] → [Simple timer service]
+
+ - [Third Party Hardware Drivers] → [Sensors] → [AD8318 - RF Meter Click (Mikroe)] → use default configuration.
+
+4. Install printf float
+
+ - Open Properties of the Project.
+
+ - Select C/C++ Build → Settings → Tool Settings → GNU ARM C Linker → General. Check Printf float.
+ ![install_float](install_float.png)
+
+5. Build and flash this example to the board.
+
+**Note :**
+
+- Make sure the SDK extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+- SDK Extension must be enabled for the project to install the " AD8318 - RF Meter Click (Mikroe)" component. Selecting this component will also include the "SPIDRV" component with instance "mikroe".
+
+## How It Works ##
+
+### Driver Layer Diagram ###
+
+![software_layer](software_layer.png)
+
+### Testing ###
+
+This example uses for measuring radio frequency power, and convert it to decibels per milliwatt value (dBm). This value is used to define signal strength in wires and cables at radio frequencies.
+
+You can launch Console that's integrated into Simplicity Studio or use a third-party terminal tool like TeraTerm to receive the data from the USB. A screenshot of the console output is shown in the figure below.
+
+![console_log](console_log.png)
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
\ No newline at end of file
diff --git a/app/documentation/example/mikroe_rf_meter_ad8318/console_log.png b/app/documentation/example/mikroe_rf_meter_ad8318/console_log.png
new file mode 100644
index 00000000..96d89854
Binary files /dev/null and b/app/documentation/example/mikroe_rf_meter_ad8318/console_log.png differ
diff --git a/app/documentation/example/mikroe_rf_meter_ad8318/create_example.png b/app/documentation/example/mikroe_rf_meter_ad8318/create_example.png
new file mode 100644
index 00000000..f5a8d3d1
Binary files /dev/null and b/app/documentation/example/mikroe_rf_meter_ad8318/create_example.png differ
diff --git a/app/documentation/example/mikroe_rf_meter_ad8318/hardware_connection.png b/app/documentation/example/mikroe_rf_meter_ad8318/hardware_connection.png
new file mode 100644
index 00000000..7bf9cfd2
Binary files /dev/null and b/app/documentation/example/mikroe_rf_meter_ad8318/hardware_connection.png differ
diff --git a/app/documentation/example/mikroe_rf_meter_ad8318/install_float.png b/app/documentation/example/mikroe_rf_meter_ad8318/install_float.png
new file mode 100644
index 00000000..e6b6e9c1
Binary files /dev/null and b/app/documentation/example/mikroe_rf_meter_ad8318/install_float.png differ
diff --git a/app/documentation/example/mikroe_rf_meter_ad8318/software_layer.png b/app/documentation/example/mikroe_rf_meter_ad8318/software_layer.png
new file mode 100644
index 00000000..3f6b165f
Binary files /dev/null and b/app/documentation/example/mikroe_rf_meter_ad8318/software_layer.png differ
diff --git a/app/documentation/example/mikroe_stepper_a3967/README.md b/app/documentation/example/mikroe_stepper_a3967/README.md
new file mode 100644
index 00000000..dac768b4
--- /dev/null
+++ b/app/documentation/example/mikroe_stepper_a3967/README.md
@@ -0,0 +1,90 @@
+# Stepper Click #
+
+## Summary ##
+
+This project shows the driver implementation of the Stepper Click module, which implements the A3967 IC with the Silicon Labs Platform.
+
+Stepper click is a complete solution for driving bipolar stepper motors with full/half and micro-steps. It features the A3967 IC from Allegro Microsystems with proprietary Satlington™ sink drivers on its outputs, which ensure high efficiency and reliable operation of the internal H-Bridges. This IC has the integrated translation section, used to simplify the control: using simple step control inputs from the host MCU, the stepper motor can be driven in both directions, with the predetermined step sizes. In addition, the output current is regulated allowing for noiseless operation of the stepper motor, with no resonance and ringing typically observed at unregulated stepper driver designs.
+
+## Required Hardware ##
+
+### Silabs Development Kits ###
+
+- [EFR32xG24 Explorer Kit - XG24-EK2703A](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview)
+
+### External Hardware ###
+
+- [Stepper Click](https://www.mikroe.com/stepper-click)
+
+- [Step Motor 5v](https://www.mikroe.com/step-motor-5v)
+
+**NOTE:**
+Tested boards for working with this example:
+
+| Board ID | Description |
+| ---------------------- | ------ |
+| BRD2703A | [EFR32xG24 Explorer Kit - XG24-EK2703A](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview) |
+| BRD4314A | [BGM220 Bluetooth Module Explorer Kit - BGM220-EK4314A](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit?tab=overview) |
+| BRD4108A | [EFR32BG22 Explorer Kit Board](https://www.silabs.com/development-tools/wireless/bluetooth/bg22-explorer-kit?tab=overview) |
+
+## Hardware Connection ##
+
+The Stepper Click Board™ supports MikroBus, so it can connect easily to EFR32xG24 Explorer Kit's MikroBus header. Be sure that the 45-degree corner of the Click Board™ matches the 45-degree white line of the Silicon Labs Explorer Kit. In this example, we use a 28BYJ-48 5V stepper motor, so the +5V power supply and GND are connected to the Stepper Click Board™. Also, four control signals for the stepper motor are connected to pins 1A, 1B, 2A, and 2B respectively. The hardware connection is shown in the image below:
+![board](image/hardware_connection.png)
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD4314A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with the filter "stepper".
+
+2. Click **Create** button on the **Third Party Hardware Drivers - A3967 - Stepper Click (Mikroe)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "EFR32xG24 Explorer Kit" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file *app/example/mikroe_stepper_a3967/app.c* (overwriting existing file), into the project root folder.
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+ - [Services] → [IO Stream] → [IO Stream: USART] → default instance name: vcom
+ - [Application] → [Utility] → [Log]
+ - [Third-Party Hardware Drivers] → [A3967 - Stepper Click (Mikroe)]
+4. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure that the Third-party Drivers Extension has already been installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+- Third-party Drivers Extension must be enabled for the project to install "A3967 - Stepper Click (Mikroe)" component.
+
+## How It Works ##
+
+According to the data sheet, when the 28BYJ-48 motor is operated in full-step mode, each step corresponds to a rotation of 5.625°. This means there are 64 steps per revolution (360°/5.625° = 64).
+
+In addition, the motor features a 1/64 reduction gear set. This means that there are in fact 4096 steps (64*64 steps per revolution).
+
+After the main program is executed, the stepper motor will start to run like the GIF below:
+
+![test](image/test.gif)
+
+You also can check the output of PWM and it look like the picture below:
+
+![pwm_signal](image/pwm.png)
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/mikroe_stepper_a3967/image/create_example.png b/app/documentation/example/mikroe_stepper_a3967/image/create_example.png
new file mode 100644
index 00000000..959c5cc1
Binary files /dev/null and b/app/documentation/example/mikroe_stepper_a3967/image/create_example.png differ
diff --git a/app/documentation/example/mikroe_stepper_a3967/image/hardware_connection.png b/app/documentation/example/mikroe_stepper_a3967/image/hardware_connection.png
new file mode 100644
index 00000000..6650721e
Binary files /dev/null and b/app/documentation/example/mikroe_stepper_a3967/image/hardware_connection.png differ
diff --git a/app/documentation/example/mikroe_stepper_a3967/image/pwm.png b/app/documentation/example/mikroe_stepper_a3967/image/pwm.png
new file mode 100644
index 00000000..a0414b50
Binary files /dev/null and b/app/documentation/example/mikroe_stepper_a3967/image/pwm.png differ
diff --git a/app/documentation/example/mikroe_stepper_a3967/image/test.gif b/app/documentation/example/mikroe_stepper_a3967/image/test.gif
new file mode 100644
index 00000000..26f035e3
Binary files /dev/null and b/app/documentation/example/mikroe_stepper_a3967/image/test.gif differ
diff --git a/app/documentation/example/silabs_ir_generate/README.md b/app/documentation/example/silabs_ir_generate/README.md
new file mode 100644
index 00000000..5b31eb4b
--- /dev/null
+++ b/app/documentation/example/silabs_ir_generate/README.md
@@ -0,0 +1,108 @@
+# IR Generator Driver #
+
+## Summary ##
+
+This project shows the implementation of IR generator driver using WSTK kit. IR Generator is widely used in remote controls, used in controlling home appliances such as TV remotes, air conditioners...
+
+## Required Hardware ##
+
+- [EFR32xG21 Wireless Gecko Starter Kit](https://www.silabs.com/development-tools/wireless/efr32xg21-wireless-starter-kit?tab=overview)
+- [IR Led](https://www.robomart.com/ir-led-3mm)
+
+**NOTE:**
+Tested boards for working with this example:
+
+| Board ID | Description |
+| ---------------------- | ------ |
+| BRD4180A | [SiLabs EFR32xG21 Radio Board BRD4180A](https://www.silabs.com/development-tools/wireless) |
+| BRD4182A | [SiLabs EFR32xG22 Radio Board BRD4182A](https://www.silabs.com/development-tools/wireless/slwrb4182a-efr32xg22-wireless-gecko-radio-board) |
+
+## Hardware Connection ##
+
+The hardware connection is shown in the image below:
+
+![board](image/hardware_connection.png "Hardware connection")
+
+The table below shows the connection between the Board and the IR LED. You can replace PD2 with another pin via config in the software component.
+
+| EFR32 pin | IR LED |
+| ---------------------- | ------ |
+| PD2 | Connect to long pin of the LED |
+| GND | Connect to short pin of the LED |
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD4180A to MyProducts, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with the filter "ir generate"
+
+2. Click **Create** button on the **Third Party Hardware Drivers - IR Generate (Silabs)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![Create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" for the "EFR32xG21 Radio Board" using Simplicity Studio v5. Use the default project settings.
+
+2. Copy the file app/example/silabs_ir_generate/app.c (overwriting existing file), into the project root folder.
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - **[Services] → [IO Stream] → [IO Stream: USART]** → default instance name: vcom
+ - **[Application] → [Utility] → [Log]**
+ - **[Platform] → [Board Control]** -> Enable Virtual COM UART
+ - **[Third Party Hardware Drivers] → [Miscellaneous] → [IR Generator (Silabs)]** → use default configuration:
+ ![config](image/default_config.png)
+
+4. Build and flash this example to the board.
+
+**Note:**
+
+- Make sure the SDK extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/third_party_hw_drivers_extension/blob/master/README.md).
+
+- SDK Extension must be enabled for the project to install "IR_GENERATE_DRV (Sillabs)" component.
+
+## API ##
+
+![image](image/IR_API.png)
+
+Based on the operation, the keypad driver API can be broken into 2 categories:
+
+- Initialization.
+ - ir_generate_init() function initialize the keypad with the callback.
+ - code_t ir_code, set the IR protocol, currently supporting NEC and SONY type.
+ - ir_callback_t cb, is called if one frame stream is sent.
+- Running the IR generates
+ - ir_generate_stream() function configures the data that desire to send and start, repeat flag use in NEC IR protocol.
+ - ir_generate_stop() function can stop the IR generate.
+
+## How It Works ##
+
+### Software Workflow ###
+
+![image](image/IR_workflow.png)
+
+After initialization, the system is in idle status. When IR send is required, configure the stream according to the given data, and send out all the stream bits. If don't get the stop command, it keeps repeating. If no need to repeat the IR signal, the system will back to idle status. Start/stop can control by key events. The demo is keep sending the IR signal after initializing, for the NEC type you can find it send 4 repeat frame then restart.
+
+### Testing ###
+
+You can use Logic Analyzer to be able to measure the signal from Carrier Pin. A screenshot of the output and an actual test image is shown in the figure below.
+
+![logging_screen](image/log.png)
+
+You can test this project with real devices from manufacturers like NEC and SONY.
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/silabs_ir_generate/image/IR_API.png b/app/documentation/example/silabs_ir_generate/image/IR_API.png
new file mode 100644
index 00000000..aaaccf7c
Binary files /dev/null and b/app/documentation/example/silabs_ir_generate/image/IR_API.png differ
diff --git a/app/documentation/example/silabs_ir_generate/image/IR_workflow.png b/app/documentation/example/silabs_ir_generate/image/IR_workflow.png
new file mode 100644
index 00000000..280555bb
Binary files /dev/null and b/app/documentation/example/silabs_ir_generate/image/IR_workflow.png differ
diff --git a/app/documentation/example/silabs_ir_generate/image/create_example.png b/app/documentation/example/silabs_ir_generate/image/create_example.png
new file mode 100644
index 00000000..9f8b8feb
Binary files /dev/null and b/app/documentation/example/silabs_ir_generate/image/create_example.png differ
diff --git a/app/documentation/example/silabs_ir_generate/image/default_config.png b/app/documentation/example/silabs_ir_generate/image/default_config.png
new file mode 100644
index 00000000..055a9051
Binary files /dev/null and b/app/documentation/example/silabs_ir_generate/image/default_config.png differ
diff --git a/app/documentation/example/silabs_ir_generate/image/hardware_connection.png b/app/documentation/example/silabs_ir_generate/image/hardware_connection.png
new file mode 100644
index 00000000..d9b0fc38
Binary files /dev/null and b/app/documentation/example/silabs_ir_generate/image/hardware_connection.png differ
diff --git a/app/documentation/example/silabs_ir_generate/image/log.png b/app/documentation/example/silabs_ir_generate/image/log.png
new file mode 100644
index 00000000..ca9e2259
Binary files /dev/null and b/app/documentation/example/silabs_ir_generate/image/log.png differ
diff --git a/app/documentation/example/silabs_pir_ira_s210st01/README.md b/app/documentation/example/silabs_pir_ira_s210st01/README.md
new file mode 100644
index 00000000..360c12aa
--- /dev/null
+++ b/app/documentation/example/silabs_pir_ira_s210st01/README.md
@@ -0,0 +1,108 @@
+# PIR Sensor Driver #
+
+## Summary ##
+
+This project shows the implementation of PIR sensor driver using the PIR sensor on the occupancy sensor EXP board.
+
+The target application of the PIR sensor would be smart lighting or alarm systems in home automation. Whenever certain motion of the human body is detected, the system will either turn on the light or the alarm.
+
+## Gecko SDK version ##
+
+GSDK v4.2.2
+
+## Required Hardware ##
+
+- [EFR32MG12 2.4 GHz 10 dBm Radio Board BRD4162A](https://www.silabs.com/documents/public/reference-manuals/brd4162a-rm.pdf)
+- Wireless Starter Kit Mainboard (BRD4001A)
+- Occupancy Sensor EXP board (BRD8030A)
+
+The driver should work with minimal porting on other series 1 EFM/EFR devices and with other
+PIR sensors having similar designs as the one on the Occupancy Sensor EXP board.
+
+**NOTE:**
+Tested boards for working with this example:
+
+| Board ID | Description |
+| ---------------------- | ------ |
+| BRD4162A | [EFR32MG12 2.4 GHz 10 dBm Radio Board BRD4162A](https://www.silabs.com/documents/public/reference-manuals/brd4162a-rm.pdf) |
+| BRD4161A | [EFR32MG12 2.4 GHz 19 dBm Radio Board BRD4161A](https://www.silabs.com/documents/public/reference-manuals/brd4161a-rm.pdf) |
+
+## Hardware Connection ##
+
+Connect the occupancy sensor EXP board to the WSTK board through the expansion header.
+
+![hardware_connection](hardware_connection.png)
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD4162A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with filter s210st01.
+
+2. Click **Create** button on the **Third Party Hardware Drivers - IRA-S210ST01 - PIR sensor (Silabs)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![create_example](create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create a "Platform - Empty C Project" project for the "EFR32MG12 Radio Board (BRD4162A)" using Simplicity Studio v5. Use the default project settings. Be sure to connect and select the "EFR32MG12 Radio Board (BRD4162A)" from the "Debug Adapters" on the left before creating a project.
+
+2. Copy the files from app/example/silabs_pir_ira_s210st01 folder into the project root folder (overwriting existing app.c).
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+ - Select the *SOFTWARE COMPONENTS* tab.
+ - Install the following components:
+ - **[Third Party Hardware Drivers] → [Sensor] → [IRA-S210ST01 - PIR Sensor (Silabs)]**.
+ - **[Platform] → [Driver] → [LED] → [Simple LED]** component with the default instance name: **led0**.
+
+## How It Works ##
+
+Wheverever motion is detected, the LED0 on the WSTK Mainboard will be turned on. If no motion is detected for 4 seconds, the LED0 will be turned off.
+
+### API Documentation ###
+
+![api](api.png)
+
+Based on the operation, the PIR sensor driver API can be broken into 4 categories:
+
+- Initialization.
+ - pir_init() function will power up the PIR sensor and initialize all peripherals required to perform the measurement
+ - pir_configure() function is not currently implemented yet. The PIR sensor we used is an analog sensor which doesn't have internal registers to program.
+- Running the Motion Detection
+ - pir_start() and pir_stop() functions are used to start/stop ADC measurements.
+ - pir_detect_motion() is a simple algorithm that tells if motion is detected. It also adaptively update the ADC threshold to trigger interrupts.
+- Callbacks
+ - pir_adc_irq_callback() function is called in ADC IRQ. It's up to the application layer to decide how to set up flags/events to call the motion detection algorithm.
+ - pir_motion_detection_callback() function is called in the motion detection algorithm to notify the application layer whenever motion on/off is detected.
+- Debug Utilities
+ - The application layer can provide a buffer for the PIR driver to save PIR samples to a sample queue for debugging purpose.
+
+### Peripherals Usage ###
+
+![peripherals](peripherals.png)
+
+The figure above shows an overview of all peripherals used in the PIR sensor driver.
+
+- Yellow blocks are external hardware components.
+- Green blocks are peripherals that can operate in EM2.
+ - 3 GPIOs, PRS, CRYTIMER(32Hz) and ADC are MUST have.
+ - OPAMP can be either external or internal.
+ - LETIMER is optional for processing/debugging samples.
+- Motion detection can only run in EM0 as shown in the blue block.
+
+### Software Workflow ###
+
+![workflow](workflow.png)
+
+After initialization, users can call pir_start() function to start ADC measurements (32Hz). If an ADC interrupt is received, host MCU will be waken up to buffer ADC samples and call the pir_adc_irq_callback function. Users should run the motion detection algorithm on the latest ADC sample to detect motions.
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
\ No newline at end of file
diff --git a/app/documentation/example/silabs_pir_ira_s210st01/api.png b/app/documentation/example/silabs_pir_ira_s210st01/api.png
new file mode 100644
index 00000000..97629b39
Binary files /dev/null and b/app/documentation/example/silabs_pir_ira_s210st01/api.png differ
diff --git a/app/documentation/example/silabs_pir_ira_s210st01/create_example.png b/app/documentation/example/silabs_pir_ira_s210st01/create_example.png
new file mode 100644
index 00000000..9d70f1c6
Binary files /dev/null and b/app/documentation/example/silabs_pir_ira_s210st01/create_example.png differ
diff --git a/app/documentation/example/silabs_pir_ira_s210st01/hardware_connection.png b/app/documentation/example/silabs_pir_ira_s210st01/hardware_connection.png
new file mode 100644
index 00000000..bc84ea60
Binary files /dev/null and b/app/documentation/example/silabs_pir_ira_s210st01/hardware_connection.png differ
diff --git a/app/documentation/example/silabs_pir_ira_s210st01/peripherals.png b/app/documentation/example/silabs_pir_ira_s210st01/peripherals.png
new file mode 100644
index 00000000..22cdaf72
Binary files /dev/null and b/app/documentation/example/silabs_pir_ira_s210st01/peripherals.png differ
diff --git a/app/documentation/example/silabs_pir_ira_s210st01/workflow.png b/app/documentation/example/silabs_pir_ira_s210st01/workflow.png
new file mode 100644
index 00000000..426043f2
Binary files /dev/null and b/app/documentation/example/silabs_pir_ira_s210st01/workflow.png differ
diff --git a/app/documentation/example/silabs_triac/README.md b/app/documentation/example/silabs_triac/README.md
new file mode 100644
index 00000000..b3830973
--- /dev/null
+++ b/app/documentation/example/silabs_triac/README.md
@@ -0,0 +1,488 @@
+# Triac Driver (Silabs) #
+
+## Overview ##
+
+Triac Driver (TRIACDRV) is a hardware device driver for Series 1 EFM32 and EFR32
+devices that uses an appropriate voltage level representation of the
+AC line voltage in order to fire a timed pulse to drive the gate on a
+triac.
+
+By using the PRS to connect one of the device's analog comparators
+(ACMP) with one of its timers (TIMERs), the triac gate enables the pulse can
+be fired automatically and with zero CPU intervention. In addition to
+initializing the necessary hardware, the driver includes functions to
+get and set the duty cycle (between 0 and 100% in 1% increments) and
+to monitor the half-wave duty cycle periods as a kind of calibration to
+account for some level of potential variation in the incoming DC
+waveform due to poor line conditions.
+
+## Required Hardware ##
+
+- [A EFM32 Tiny Gecko TG11 Starter Kit](https://www.silabs.com/development-tools/mcu/32-bit/efm32tg11-starter-kit?tab=overview)
+
+- An oscilloscope can be used to observe both this stimulus and the gate enable pulse output generated by the driver.
+
+## Hardware Connection ##
+
+Using a jumper wire, connect expansion header pins 3 (PC0, the ACMP input) and 12 (PC14, the 60 Hz stimulus). Attach oscilloscope probes to expansion header pins 10 (PC8) and 12 to observe the gate enable pulse output relative to the 60 Hz input.
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD2102A to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with filter: triac.
+
+2. Click **Create** button on the **TThird Party Hardware Drivers - Triac Driver (Silabs)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![create_example](image/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create a "Platform - Empty C Project" project for the "EFM32 Tiny Gecko TG11 Starter Kit (BRD2102A)" using Simplicity Studio v5.
+2. Copy the *app/example/silabs_triac/app.c* file into the project root folder (overwriting existing).
+
+3. Install the software components:
+
+ - Open the .slcp file in the project.
+
+ - Select the SOFTWARE COMPONENTS tab.
+
+ - Install the following components:
+
+ - [Platform] → [Peripheral] → [LETIMER].
+ - [Platform] → [Driver] → [Button] → [Simple Button] → [btn0, btn1].
+ - [Third Party Hardware Drivers] → [Miscellaneous] → [Triac Driver (Silabs)] → use default configuration
+
+4. Build and flash the project to your device.
+
+**Note:**
+
+- Make sure the SDK extension already be installed. If not please follow [this documentation](https://github.com/SiliconLabs/platform_hardware_drivers_sdk_extensions/blob/master/README.md).
+
+- SDK Extension must be enabled for the project to install "Triac Driver (Silabs)" component.
+
+## Device Resource Requirements ##
+
+As mentioned above, TRIACDRV uses the PRS to link one ACMP with one
+TIMER to generate the gate enable pulse. The specific requirements are
+as follows:
+
+**1. ACMP**
+
+The input voltage, which is some user-conditioned representation of the
+AC line voltage (what this specifically means is discussed later), must
+be between 0 volts and the lesser of AVDD or IOVDD because the ACMP is
+supplied by AVDD, and the input signal is routed using the APORT.
+
+This permits the widest possible input range because Series 1 devices
+require that AVDD ≥ IOVDD and that VREGVDD = AVDD on devices with the
+DCDC. It does, however, mean that the representation of the AC line must
+be between 0 volts and IOVDD in systems where IOVDD < AVDD (e.g. when
+IOVDD = 1.8V to interface with digital peripherals and GPIO on
+high-performance processors that do not support some kind of 3 volts
+nominal I/O rail).
+
+Selection of the APORT channel routed to the ACMP positive input and the
+zero-crossing threshold voltage is up to the user and handled as part
+of initializing the driver.
+
+**2. TIMER**
+
+TRIACDRV requires a single 16-bit TIMER of which it uses capture/compare
+(CC) channels 0, 1, and 2. For all practical purposes, CC channel 3 should
+be considered unavailable to end-user code as TRIACDRV must retain control
+of the TIMER counter and its initialization.
+
+Use of the WTIMER is currently unsupported.
+
+**3. PRS**
+
+TRIACDRV requires three PRS channels. The zero-crossing detection output
+from the ACMP is routed to the selected TIMER using one PRS channel. TIMER
+channels CC1 and CC2 are ANDed together using two adjacent PRS channels to
+create the triac gate enable pulse. When the AND option is used with a pair
+of PRS channels, channel N and is ANDed together with channel N + 1 such
+that channel N is the resulting output.
+
+Consequently, specifying PRS channel N for the TIMER means that channel
+N + 1 is also used and that the port, pin, and location specified for the
+output must be one of the available locations for PRS channel N (PRS_CHn).
+
+**4. Pins**
+
+As noted above, the user-conditioned representation of the AC line voltage
+is input on one ACMP pin via the APORT. Refer to Analog Port (APORT) Client
+Maps in section 5 of the datasheet to see the APORT inputs available for a
+given ACMP.
+
+One pin is required for the gate to enable pulse output. It must be a GPIO
+pin for which the PRS_CH alternate function corresponds to the selected
+PRS channel chosen for the TIMER. For example, if PRS channel 8 is chosen
+for the TIMER, then the pin chosen as an output must have PRS_CH8 as an
+alternate function.
+
+**5. Energy Modes**
+
+Because the TIMER counter must run in order to output gate enable pulses
+in response to zero-crossing events, TRIACDRV is restricted to running in
+EM0 or EM1. To enter EM2 (or lower), application software should first set
+the output duty cycle to 0% by calling triacdrv_set_duty_cycle(). Upon
+returning to EM0, there is no need to re-initialize the driver; the output
+can be re-enabled simply by setting the duty cycle to a non-zero value.
+
+## API ##
+
+![TRIACDRV Block Diagram](image/triacdrv_diagram.png)
+
+### Overview ###
+
+TRIACDRV works on the premise that…
+
+* the AC line voltage appears to be a symmetrical waveform consisting of
+two half waves demarcated by zero-crossings and that
+* the TIMER which measures this waveform is operating many times faster
+(e.g. somewhere in the single-digit MHz range)
+
+…such that any asymmetry in the duration of the two half waves is
+effectively invisible to the human eye for dimming purposes when the net
+effective difference is relatively small.
+
+By using the PRS to connect the ACMP output with the TIMER start-reload
+input, TRIACDRV is able to continually start and reload the counter in
+response to zero-crossing events. Capture/compare channel 0 (CC0) of the
+selected timer captures the time of this reload event, which is the
+duration of the half-wave.
+
+During initialization and in response to calling the TRIACDRV_Calibrate()
+function, the driver captures this half-wave duration and saves both the
+largest and smallest values observed. TRIACDRV_SetDutyCycle() uses this
+information to determine the positioning of the gate enable output pulse.
+
+For example, if the duty cycle is set to 30%, the rising edge is of the
+output pulse is positioned at 30% of the smallest count value observed;
+the falling edge is positioned at this count plus the user-specified
+pulse duration later. When 0% duty cycle is specified, the output pulse
+is positioned to start after the maximum half wave count such that the
+counter reload-start occurs before the pulse can ever be generated.
+
+As mentioned above, the rising and falling edges of the output pulse
+are positioned with respect to the half-wave duration and the specified
+duty cycle. TIMER channel CC1 is used for the pulse rising edge and, if
+it were output to a pin, would initially be low. Conversely, TIMER
+channel CC2 is used for the falling edge and would be initially high if
+output to a pin.
+
+To combine these two signals into the desired output pulse, CC1 and CC2
+are assigned to user-specified PRS channel N and N + 1, respectively.
+This sequential assignment is mandatory because the PRS has the ability
+to perform some limited logic operations on two adjacent channels.
+Specifically, the PRS has the ability to AND a given channel with the
+next higher-numbered channel (ANDNEXT), and this is used here to AND
+CC1 (rising edge), which goes from low to high, with CC2 (falling edge),
+which goes from high to low. The resulting pulse is driven on the
+user-selected PRS_CH pin associated with channel N.
+
+### Using the TRIACDRV ###
+
+Use of TRIACDRV is modeled after emlib components. An initialization
+function takes a pointer to an initialization structure that specifies
+the fixed configuration parameters for the driver. Other functions
+adjust the behavior of the driver once it is running.
+
+A project using TRIACDRV must #include triacdrv.h in source files that
+call the driver's functions.
+
+#### Data Structures ####
+
+ typedef struct
+ {
+ // ACMP used for zero crossing detection
+ ACMP_TypeDef *acmp;
+
+ // APORT ACMP input channel
+ ACMP_Channel_TypeDef acmpInput;
+
+ // PRS channel used to link ACMP and TIMER
+ uint32_t acmpPrsChannel;
+
+ // TIMER used for half-wave measurement and output generation
+ TIMER_TypeDef *timer;
+
+ /*
+ * Base PRS channel used for gate enable output pulse. Two
+ * adjacent channels (N and N + 1) are ANDed together to form
+ * the output pulse.
+ */
+ uint32_t timerPrsBaseChannel;
+
+ /*
+ * Output port, pin, and location for timerPrsBaseChannel. This
+ * must be one of the PRS_CH pin options for the PRS channel
+ * selected, e.g. if PRS channel 4 is selected as the
+ * timerPrsBaseChannel on EFM32TG11, then the pin options are PC8
+ * and PF1.
+ */
+ GPIO_Port_TypeDef timerPrsOutputPort;
+ uint32_t timerPrsOutputPin;
+ uint32_t timerPrsOutputLoc;
+
+ // Input waveform type
+ TRIACDRV_InputWave_Typedef inputWave;
+
+ // Threshold voltage for zero-crossing in mV
+ uint32_t zeroThreshold;
+
+ // AVDD supply voltage in mV
+ uint32_t avdd;
+
+ // Gate enable pulse width in microseconds
+ uint32_t pulseWidth;
+
+ // Triac initially on?
+ bool initOn;
+ } TRIACDRV_Init_TypeDef;
+
+TRIACDRV_Init_TypeDef is the initialization structure passed to the
+TRIACDRV_Init() function. The members have self-explanatory names
+and, unless explicitly disabled, are bounds-checked during
+initialization.
+
+#### Enumerations ####
+
+ typedef enum
+ {
+ triacInputRectifiedSine, // Rectified sine wave (no negative half wave) input
+ triacInputOffsetSine, // Offset sine wave with zero-crossing at 50%
+ } TRIACDRV_InputWave_Typedef;
+
+Allowable input waveforms are a rectified sine wave or an offset sine
+wave that oscillates between ground and AVDD (or IOVDD) and has a
+midpoint at half the specified analog input voltage.
+
+#### Macros ####
+
+ #define TRIACDRV_MAX_CAL_COUNT 60
+
+ #define TRIACDRV_MAX_ENABLE_PULSE_WIDTH 200
+
+ #define TRIACDRV_MIN_ZERO_THRESHOLD 5
+ #define TRIACDRV_MAX_ZERO_THRESHOLD 500
+
+ #define TRIACDRV_MIN_AVDD 1800
+ #define TRIACDRV_MAX_AVDD 3800
+
+ #define TRIACDRV_MIN_TIMER_FREQUENCY 1000000
+
+These macros specify the bounds-checked ranges for parameters that are
+specified or otherwise controlled (the TIMER clock frequency) by the
+user.
+
+#### Functions ####
+
+ sl_status_t triacdrv_init(const TRIACDRV_Init_TypeDef *init)
+
+triacdrv_init() takes a pointer to the initialization structure
+described above. Unless explicitly disabled at compile time, it
+bounds-checks the hardware resources assigned to the driver, as well as
+the user-specified parameters that govern the input and output signals.
+It can return the following possible status codes:
+
+**1. SL_STATUS_OK**
+
+Denotes successful driver initialization.
+
+**2. SL_STATUS_INVALID_RANGE**
+
+One or more of the zeroThreshold, avdd, or pulseWidth initialization
+structure members is out of range. It can also mean that the selected
+TIMER clock is less than 1 MHz (TRIACDRV_MIN_TIMER_FREQUENCY in
+triacdrv.h), which means that the HFPERCLK has been prescaled to less
+than 1 MHz on a Series 1 device.
+
+**3. SL_STATUS_INVALID_CONFIGURATION**
+
+One of the user-specified hardware parameters is invalid. This can mean
+that the selected ACMP or TIMER does not exist on the chip against which
+the project is being built (e.g. specifying ACMP2 on EFM32TG11, which has
+only ACMP0 and ACMP1).
+
+It can also indicate a similar problem with the selection of PRS channels
+(e.g. one of the selected channels does not exist on the device, including
+one of the two adjacent channels required to generate the output pulse).
+
+Finally, there can be a problem with output selection. This can be a
+non-existent I/O port or pin or a possibly non-existent location for
+the PRS_CH alternate function. Note that the bounds-checking for the
+latter is not absolute. Alternate functions are not always contiguously
+defined (e.g. PRS_CH4 has only locations 0 and 2 on EFM32TG11).
+
+ sl_status_t triacdrv_set_duty_cycle(uint32_t duty)
+
+Sets the duty cycle (positioning) of the gate enable pulse to an integer
+value between 0 (off) and 100% (always on). The following status codes
+can be returned:
+
+**1. SL_STATUS_NOT_INITIALIZED**
+
+Returned if TRIACDRV_Init() has not been called and returned
+SL_STATUS_OK.
+
+**2. SL_STATUS_INVALID_RANGE**
+
+Returned if a duty cycle greater than 100% is specified.
+
+ uint32_t triacdrv_get_duty_cycle(void)
+
+Returns the previously set duty cycle or 0 if TRIACDRV has not been
+successfully initialized.
+
+ sl_status_t triacdrv_calibrate(uint32_t count)
+
+triacdrv_calibrate() takes up to TRIACDRV_MAX_CAL_COUNT measurments of
+the measures the half-wave count and saves the largest and smallest
+values found. This allows the driver to attempt to more accurately
+place the gate enable pulse in the event that there is some asymmetry
+in the AC waveform due to poor line conditions. The following status
+codes can be returned:
+
+**1. SL_STATUS_NOT_INITIALIZED**
+
+Returned if TRIACDRV_Init() has not been called and returned
+SL_STATUS_OK.
+
+**2. SL_STATUS_INVALID_RANGE**
+
+Returned if called with a half-wave count greater than
+TRIACDRV_MAX_CAL_COUNT.
+
+## How It Works ##
+
+The demonstration project is in app.c file which shows how to initialize and
+invoke TRIACDRV. Code flow is as follows:
+
+1. Both the LFXO and HFXO are initialized, and the HFXO is selected as
+the source of the HFCLOCK. This permits the TIMER used by TRIACDRV to
+run with a fast and accurate reference clock.
+
+2. GPIO pins connected to push buttons 0 and 1 are configured as inputs
+with active pull-ups, and their associated interrupts are enabled.
+Additionally, the pin used to output the 60 Hz LETIMER square
+wave stimulus is set to use the lowest available slew rate setting.
+
+3. The LETIMER is configured to output a 60 Hz square wave with 50%
+duty cycle to be used as stimulus for the rectified sine wave input
+configuration.
+
+4. The default TRIACDRV initialization structure is modified to use the
+specific hardware resources available on the EFM32TG11 Starter Kit and
+to use the maximum supported output enable pulse width so that it is
+visible on an oscilloscope when displayed along with the input
+stimulus waveform.
+
+5. triacdrv_init() is called and halts if SL_STATUS_OK is not returned.
+
+6. The output duty cycle is set to 25% and the driver is allowed to
+calibrate over 60 half-waves.
+
+7. At this point, the device enters EM1 and waits for an interrupt in
+response to button 0 or 1 being pressed. No CPU cycles are utilized to
+generate the output pulse as the PRS allows TIMER0 to do this
+automatically in response to zero-crossings detected by ACMP0.
+
+8. When a button press is detected, the GPIO interrupt handler
+decrements (button 0) or increments (button 1) the duty cycle and calls
+triacdrv_set_duty_cycle() to have the driver update the output.
+
+9. Attach oscilloscope probes to expansion header pins 10 (PC8) and 12
+to observe the gate enable pulse output relative to the 60 Hz input.
+You should expect a similar output to the one below.
+
+ ![](image/oscilloscope_output.png)
+
+## Input Waveform Considerations ##
+
+No microcontroller of any sort, regardless of the vendor, has input pad
+structures that permit it to be interfaced directly with the AC mains.
+Some kind of external hardware is required to translate the positive and
+negative high voltages swings into something between ground and the
+microcontroller's I/O voltage supply.
+
+![AC Mains Voltage](image/triacdrv_ac_sine.png)
+
+TRIACDRV has no awareness of the external hardware that might be used to
+do this. However, it does provide a means to select one of two supported
+ways in which the AC waveform can be presented.
+
+One is as a rectified sine wave in which the voltage swings are scaled
+between GND and AVDD (or IOVDD, as noted above). The expected waveform
+for this option is shown below:
+
+![Rectified Sine Wave](image/triacdrv_rectified_sine.png)
+
+When using this option, the inputWave member of the initialization
+structure must be set to triacInputRectifiedSine. Use this option for
+other AC mains representations that present the zero-crossings as
+comparator threshold transitions near GND. The 60 Hz square wave output
+provided by the letimer60Hz() function in the demonstration project is
+an example of this.
+
+The other input option is an offset sine wave, which is simply a
+scaled representation of the AC mains voltage that swings between GND
+and AVDD (or IOVDD). The expected waveform for this option is shown
+below:
+
+![Offset Sine Wave](image/triacdrv_offset_sine.png)
+
+Ideally, the waveform midpoint should be one half AVDD (or IOVDD), but
+the avdd member of the initialization structure effectively specifies
+the peak input voltage seen at the pin.
+
+## Gate Enable Output
+
+The gate enable output pulse is driven on a digital I/O pin that
+toggles between GND and IOVDD.
+
+## Disabling Hardware Resource Checking ##
+
+TRIACDRV can be compiled with hardware resource checking disabled at
+build time. Add TRIACDRV_DISABLE_HW_RESOURCE_CHECKING to
+Properties -> C/C++ Build -> Setting -> GNU ARM C Compiler -> Symbols
+in Simplicity Studio or define this symbol as part of the compiler
+invocation command line (e.g. -DTRIACDRV_DISABLE_HW_RESOURCE_CHECKING
+in GCC or the equivalent in IAR).
+
+Depending on the optimization level, doing so can save up to 324 bytes
+of flash space on the EFM32TG11. The savings on other devices vary
+depending on the number of ACMPs and TIMERs with EFM32xG1/EFR32xG1
+devices seeing a reduction of up to 304 bytes and other devices being
+in the range of 360 to 388 bytes.
+
+Once a TRIACDRV configuration is known to be working on its intended
+target, disabling hardware resource checking is advisable in order to
+recover some flash space for use elsewhere in the application.
+
+## Porting to Other EFM32 and EFR32 Series 1 Devices ##
+
+Apart from any issues of pin or alternate function availability on a
+given device or board, the TRIACDRV code itself should not require
+modifications. The user-provided initialization structure of type
+TRIACDRV_Init_TypeDef, will, of course, need to be customized for the
+target device or board.
+
+Note that the minimum supported AVDD on EFM32xG1 and EFR32xG1 devices is
+1.85V, which is 50 mV higher than the 1.8V minimum on all other Series 1
+devices. TRIACDRV_MIN_AVDD in triacdrv.h is set to the latter value.
+
+TRIACDRV provides a debugging facility that might be helpful if problems
+are experienced when attempting to build the driver on another target.
+This mechanism consists of various internal signals that can be output to
+pins specified in the triacdrv_config.h file.
+
+These outputs are globally enabled at build time by the TRIACDRV_DEBUG
+symbol and are, in fact, enabled in the demonstration project. No actual
+debug code is generated because the symbols that specify the port, pin,
+and routing location for each of these signals are only defined when
+their top-level enable symbol is uncommented.
diff --git a/app/documentation/example/silabs_triac/image/create_example.png b/app/documentation/example/silabs_triac/image/create_example.png
new file mode 100644
index 00000000..e18e0fa5
Binary files /dev/null and b/app/documentation/example/silabs_triac/image/create_example.png differ
diff --git a/app/documentation/example/silabs_triac/image/oscilloscope_output.png b/app/documentation/example/silabs_triac/image/oscilloscope_output.png
new file mode 100644
index 00000000..a1487d95
Binary files /dev/null and b/app/documentation/example/silabs_triac/image/oscilloscope_output.png differ
diff --git a/app/documentation/example/silabs_triac/image/triacdrv_ac_sine.png b/app/documentation/example/silabs_triac/image/triacdrv_ac_sine.png
new file mode 100644
index 00000000..03b34e67
Binary files /dev/null and b/app/documentation/example/silabs_triac/image/triacdrv_ac_sine.png differ
diff --git a/app/documentation/example/silabs_triac/image/triacdrv_diagram.png b/app/documentation/example/silabs_triac/image/triacdrv_diagram.png
new file mode 100644
index 00000000..02711142
Binary files /dev/null and b/app/documentation/example/silabs_triac/image/triacdrv_diagram.png differ
diff --git a/app/documentation/example/silabs_triac/image/triacdrv_offset_sine.png b/app/documentation/example/silabs_triac/image/triacdrv_offset_sine.png
new file mode 100644
index 00000000..99c571fe
Binary files /dev/null and b/app/documentation/example/silabs_triac/image/triacdrv_offset_sine.png differ
diff --git a/app/documentation/example/silabs_triac/image/triacdrv_rectified_sine.png b/app/documentation/example/silabs_triac/image/triacdrv_rectified_sine.png
new file mode 100644
index 00000000..eb437cc3
Binary files /dev/null and b/app/documentation/example/silabs_triac/image/triacdrv_rectified_sine.png differ
diff --git a/app/documentation/example/sparkfun_ir_array_amg88xx/README.md b/app/documentation/example/sparkfun_ir_array_amg88xx/README.md
new file mode 100644
index 00000000..e9b6eed2
--- /dev/null
+++ b/app/documentation/example/sparkfun_ir_array_amg88xx/README.md
@@ -0,0 +1,101 @@
+# AMG8833 Grid-EYE Infrared Array Breakout Driver #
+
+## Summary ##
+
+This project shows the implementation of the [Panasonic amg88xx infrared array](https://industry.panasonic.eu/components/sensors/industrial-sensors/grid-eye/amg88xx-high-performance-type/amg8833-amg8833) driver using the [EFR32xG24 Dev Kit](https://www.silabs.com/development-tools/wireless/efr32xg24-dev-kit?tab=overview) and the [SparkFun Grid-EYE AMG8833 infrared array](https://www.sparkfun.com/products/14607). The driver includes every known functionality of the amg88xx device, such as sensor readings, power settings, interrupt setup, and more.
+
+The Grid-EYE from Panasonic is an 8x8 thermopile array. This means you have a square array of 64 pixels each capable of independent temperature detection. It’s like having thermal camera (or Predator’s vision), just in really low resolution. It's part of SparkFun's Qwiic system, so it is easier to connect to get your low-resolution infrared image.
+## Required Hardware ##
+
+- [EFR32xG24 Dev Kit (BRD2601B)](https://www.silabs.com/development-tools/wireless/efr32xg24-dev-kit?tab=overview)
+- [SparkFun Grid-EYE Infrared Array Breakout - AMG8833 (Qwiic)](https://www.sparkfun.com/products/14607)
+
+**NOTE:**
+Tested boards for working with this example:
+
+| Board ID | Description |
+| ---------------------- | ------ |
+| BRD2704A | [SparkFun Thing Plus Matter - MGM240P - BRD2704A](https://www.sparkfun.com/products/20270) |
+| BRD2601B | [EFR32xG24 Dev Kit - xG24-DK2601B](https://www.silabs.com/development-tools/wireless/efr32xg24-dev-kit?tab=overview) |
+| BRD2703A | [EFR32xG24 Explorer Kit - XG24-EK2703A](https://www.silabs.com/development-tools/wireless/efr32xg24-explorer-kit?tab=overview) |
+| BRD4108A | [BG22 Bluetooth SoC Explorer Kit - BG22-EK4108A](https://www.silabs.com/development-tools/wireless/bluetooth/bg22-explorer-kit?tab=overview) |
+| BRD4314A | [BGM220 Bluetooth Module Explorer Kit - BGM220-EK4314A](https://www.silabs.com/development-tools/wireless/bluetooth/bgm220-explorer-kit?tab=overview) |
+
+## Connections Required ##
+
+The breakout board is connected to the dev kit with a Qwiic connector
+
+![Dev kit connection diagram](images/dev_kit.jpg)
+
+## Setup ##
+
+You can either create a project based on an example project or start with an empty example project.
+
+### Create a project based on an example project ###
+
+1. From the Launcher Home, add the BRD2601B to My Products, click on it, and click on the **EXAMPLE PROJECTS & DEMOS** tab. Find the example project with filter "amg88xx".
+
+2. Click **Create** button on the **Third Party Hardware Drivers - AMG88XX - Grid-EYE Infrared Array Breakout (Sparkfun)** example. Example project creation dialog pops up -> click Create and Finish and Project should be generated.
+![Create_example](images/create_example.png)
+
+3. Build and flash this example to the board.
+
+### Start with an empty example project ###
+
+1. Create an "Empty C Project" project for the EFR32xG24 Dev Kit using SimplicityStudio 5. Use the default project settings. Be sure to connect and select the EFR32xG24 Dev Kit from the "Debug Adapters" on the left before creating a project.
+
+2. Then copy the files [app.c](../../../example/sparkfun_ir_array_amg88xx/app.c), [app_cli_command_table.c](../../../example/sparkfun_ir_array_amg88xx/app_cli_command_table.c), [app_ir_array_cli_cmds.c](../../../example/sparkfun_ir_array_amg88xx/app_ir_array_cli_cmds.c) into the project root folder and overwriting existing file.
+
+3. Install software components in the .slcp
+
+ - **[Services] → [IO Stream] → [IO Stream: USART]** → default instance name: vcom
+ - **[Services] → [Command Line interface] → [CLI Instance(s)]** → new instance name: vcom
+ - **[Third Party Hardware Drivers] → [Sensors] → [AMG88XX - Grid-EYE Infrared Array Breakout (Sparkfun)] → use default configuration**
+
+4. Save the files, build and ready to flash or debug.
+
+5. Launch a terminal or console, open the communication to your device.
+
+6. The device communicates over CLI. If you type help, you will see a description how to control the device.
+
+## How It Works ##
+
+The following diagram presents the operation of the driver.
+
+![Usage example](images/IR_array_struct.png)
+
+Application only needs to call amg88xx_init() function once at startup. With amg88xx_get_sensor_array_temperatures() function, it is possible to request an array of temperatures for all 64 pixels. For more features or possibilities, please refer to the API function descriptions found in amg88xx_get_sensor_array_temperatures.h.
+
+The amg88xx_init() requires 2 parameters: an I2CSPM instance and an I2C server address.
+The I2CSPM instance is created by adding the I2CSPM software component. The I2C address for the AMG8833 module is 0x69, so it's recommended to use the AMG88XX_ADDRESS_OPEN macro. You have to select the temperature scale (either Celsius, or Fahrenheit) to display the temperature.
+
+However, it's possible to change the server address by entering a custom address as a parameter.
+
+## File and API Documentation ##
+
+ir_array_amg88xx_driver - This is the top-level API implementation.
+
+- `amg88xx_init` : Initialise the driver.
+- `amg88xx_get_thermistor_temperature` : Gets the thermistor temperature.
+- `amg88xx_get_sensor_array_temperatures` : Gets the temperatures of the IR sensor array.
+- `amg88xx_wake` : Puts the device to normal mode from any other state.
+- `amg88xx_sleep` : Puts device into sleep mode.
+- `amg88xx_60_sec_standby` : Puts the device into 60 seconds update interval mode.
+- `amg88xx_10_sec_standby` : Puts the device into 10 seconds update interval mode.
+- `amg88xx_enable_moving_average` : Enables "Twice Moving Average".
+- `amg88xx_disable_moving_average` : Disables "Twice Moving Average".
+
+## Generating image with Python ##
+
+There is a python script included in the repository [temperatue_array_visualiser.py](temperatue_array_visualiser.py) which could control the device over serial port and print out the actual temperature array. In the script you can setup your serial port number.
+The required python package for the app: numpy, seaborn, matplotlib.pylab, pyserial.
+
+Below is the thermal image which is generated by the [temperatue_array_visualiser.py](temperatue_array_visualiser.py) script.
+
+![thermal_image](images/thermal_image.png)
+
+## Report Bugs & Get Support ##
+
+To report bugs in the Application Examples projects, please create a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo. Please reference the board, project, and source files associated with the bug, and reference line numbers. If you are proposing a fix, also include information on the proposed fix. Since these examples are provided as-is, there is no guarantee that these examples will be updated to fix these issues.
+
+Questions and comments related to these examples should be made by creating a new "Issue" in the "Issues" section of [third_party_hw_drivers_extension](https://github.com/SiliconLabs/third_party_hw_drivers_extension) repo.
diff --git a/app/documentation/example/sparkfun_ir_array_amg88xx/images/IR_array_struct.png b/app/documentation/example/sparkfun_ir_array_amg88xx/images/IR_array_struct.png
new file mode 100644
index 00000000..7e3ebfd7
Binary files /dev/null and b/app/documentation/example/sparkfun_ir_array_amg88xx/images/IR_array_struct.png differ
diff --git a/app/documentation/example/sparkfun_ir_array_amg88xx/images/create_example.png b/app/documentation/example/sparkfun_ir_array_amg88xx/images/create_example.png
new file mode 100644
index 00000000..dd2d1bd9
Binary files /dev/null and b/app/documentation/example/sparkfun_ir_array_amg88xx/images/create_example.png differ
diff --git a/app/documentation/example/sparkfun_ir_array_amg88xx/images/dev_kit.jpg b/app/documentation/example/sparkfun_ir_array_amg88xx/images/dev_kit.jpg
new file mode 100644
index 00000000..9d1c8d11
Binary files /dev/null and b/app/documentation/example/sparkfun_ir_array_amg88xx/images/dev_kit.jpg differ
diff --git a/app/documentation/example/sparkfun_ir_array_amg88xx/images/thermal_image.png b/app/documentation/example/sparkfun_ir_array_amg88xx/images/thermal_image.png
new file mode 100644
index 00000000..54d8652a
Binary files /dev/null and b/app/documentation/example/sparkfun_ir_array_amg88xx/images/thermal_image.png differ
diff --git a/app/documentation/example/sparkfun_ir_array_amg88xx/temperatue_array_visualiser.py b/app/documentation/example/sparkfun_ir_array_amg88xx/temperatue_array_visualiser.py
new file mode 100644
index 00000000..16f7891c
--- /dev/null
+++ b/app/documentation/example/sparkfun_ir_array_amg88xx/temperatue_array_visualiser.py
@@ -0,0 +1,46 @@
+import numpy as np
+import seaborn as sns
+import serial.tools.list_ports
+import matplotlib.pylab as plt
+
+plt.style.use("seaborn")
+
+serialInst = serial.Serial()
+
+def init_uart():
+ serialInst.baudrate = 115200
+ # setup the serial Port
+ serialInst.port = "COM16"
+ serialInst.open()
+
+def receive_uart():
+ serialInst.write(b'temperature array \n')
+ # read back the send package
+ serialInst.readline()
+ packet = serialInst.readline()
+ temperatures_array = str(packet)
+ # split the two characters from the begin
+ temperatures_array = temperatures_array[2:-1]
+ temperatures_array = temperatures_array.split(",")
+ # remove the last element because it is a line break
+ temperatures_array.pop(64)
+ create_thermal_image(temperatures_array)
+
+
+def create_thermal_image(temps):
+ data = np.mat(temps, dtype=float)
+ data = data.reshape(8, 8)
+ plt.figure(figsize=(8, 8))
+ plt.title("HeatMap using Seaborn Method")
+ sns.heatmap(data)
+ plt.pause(5)
+ plt.close()
+
+
+
+if __name__ == '__main__':
+ init_uart()
+ i = 0
+ while i<10:
+ receive_uart()
+ i+=1
\ No newline at end of file
diff --git a/app/example/adafruit_rgb_led_is31fl3741/adafruit_rgb_led_is31fl3741.slcp b/app/example/adafruit_rgb_led_is31fl3741/adafruit_rgb_led_is31fl3741.slcp
index 3e428ae7..6a47d818 100644
--- a/app/example/adafruit_rgb_led_is31fl3741/adafruit_rgb_led_is31fl3741.slcp
+++ b/app/example/adafruit_rgb_led_is31fl3741/adafruit_rgb_led_is31fl3741.slcp
@@ -39,7 +39,7 @@ define:
- {name: DEBUG_EFM}
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/adafruit_rgb_led_is31fl3741/connection.png
- path: ../../documentation/example/adafruit_rgb_led_is31fl3741/config.png
diff --git a/app/example/maxim_fuel_gauge_max17048/maxim_fuel_gauge_max17048.slcp b/app/example/maxim_fuel_gauge_max17048/maxim_fuel_gauge_max17048.slcp
index e17dcfe7..66b8bd86 100644
--- a/app/example/maxim_fuel_gauge_max17048/maxim_fuel_gauge_max17048.slcp
+++ b/app/example/maxim_fuel_gauge_max17048/maxim_fuel_gauge_max17048.slcp
@@ -41,7 +41,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/maxim_fuel_gauge_max17048/overview.png
- path: ../../documentation/example/maxim_fuel_gauge_max17048/log.png
diff --git a/app/example/mikroe_accel5_bma400/mikroe_accel5_bma400_i2c.slcp b/app/example/mikroe_accel5_bma400/mikroe_accel5_bma400_i2c.slcp
index 9b7c0ddc..6b4f24e8 100644
--- a/app/example/mikroe_accel5_bma400/mikroe_accel5_bma400_i2c.slcp
+++ b/app/example/mikroe_accel5_bma400/mikroe_accel5_bma400_i2c.slcp
@@ -39,7 +39,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_accel5_bma400/image/hardware_connection.png
directory: "image"
diff --git a/app/example/mikroe_accel5_bma400/mikroe_accel5_bma400_spi.slcp b/app/example/mikroe_accel5_bma400/mikroe_accel5_bma400_spi.slcp
index d9168b14..af577ffe 100644
--- a/app/example/mikroe_accel5_bma400/mikroe_accel5_bma400_spi.slcp
+++ b/app/example/mikroe_accel5_bma400/mikroe_accel5_bma400_spi.slcp
@@ -39,7 +39,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_accel5_bma400/image/hardware_connection.png
directory: "image"
diff --git a/app/example/mikroe_alcohol_mq3/mikroe_alcohol_mq3.slcp b/app/example/mikroe_alcohol_mq3/mikroe_alcohol_mq3.slcp
index 25ddc9ed..d2e7af18 100644
--- a/app/example/mikroe_alcohol_mq3/mikroe_alcohol_mq3.slcp
+++ b/app/example/mikroe_alcohol_mq3/mikroe_alcohol_mq3.slcp
@@ -39,7 +39,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_alcohol_mq3/create_project.png
- path: ../../documentation/example/mikroe_alcohol_mq3/console_log.png
diff --git a/app/example/mikroe_barcode2_em3080w/mikroe_barcode2_em3080w.slcp b/app/example/mikroe_barcode2_em3080w/mikroe_barcode2_em3080w.slcp
index 72c54f1b..51b45ef1 100644
--- a/app/example/mikroe_barcode2_em3080w/mikroe_barcode2_em3080w.slcp
+++ b/app/example/mikroe_barcode2_em3080w/mikroe_barcode2_em3080w.slcp
@@ -40,7 +40,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_barcode2_em3080w/hardware_connection.png
- path: ../../documentation/example/mikroe_barcode2_em3080w/create_example.png
diff --git a/app/example/mikroe_brushless16_lb11685av/mikroe_brushless16_lb11685av.slcp b/app/example/mikroe_brushless16_lb11685av/mikroe_brushless16_lb11685av.slcp
index 87df15cd..29894c84 100644
--- a/app/example/mikroe_brushless16_lb11685av/mikroe_brushless16_lb11685av.slcp
+++ b/app/example/mikroe_brushless16_lb11685av/mikroe_brushless16_lb11685av.slcp
@@ -43,7 +43,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
ui_hints:
highlight:
- path: README.md
diff --git a/app/example/mikroe_buzz2_cmt_8540s_smt/mikroe_buzz2_cmt_8540s_smt.slcp b/app/example/mikroe_buzz2_cmt_8540s_smt/mikroe_buzz2_cmt_8540s_smt.slcp
index 31c8fad6..33ef4fd0 100644
--- a/app/example/mikroe_buzz2_cmt_8540s_smt/mikroe_buzz2_cmt_8540s_smt.slcp
+++ b/app/example/mikroe_buzz2_cmt_8540s_smt/mikroe_buzz2_cmt_8540s_smt.slcp
@@ -38,7 +38,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_buzz2_cmt_8540s_smt/create_example.png
- path: ../../documentation/example/mikroe_buzz2_cmt_8540s_smt/log.png
diff --git a/app/example/mikroe_captouch2_cap1166/mikroe_captouch2_cap1166.slcp b/app/example/mikroe_captouch2_cap1166/mikroe_captouch2_cap1166.slcp
index 87271445..a1f36622 100644
--- a/app/example/mikroe_captouch2_cap1166/mikroe_captouch2_cap1166.slcp
+++ b/app/example/mikroe_captouch2_cap1166/mikroe_captouch2_cap1166.slcp
@@ -39,7 +39,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_captouch2_cap1166/hardware_connection.png
- path: ../../documentation/example/mikroe_captouch2_cap1166/create_example.png
diff --git a/app/example/mikroe_co_mq7/mikroe_co_mq7.slcp b/app/example/mikroe_co_mq7/mikroe_co_mq7.slcp
index de1c9acd..c650ff91 100644
--- a/app/example/mikroe_co_mq7/mikroe_co_mq7.slcp
+++ b/app/example/mikroe_co_mq7/mikroe_co_mq7.slcp
@@ -49,7 +49,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
ui_hints:
highlight:
- path: README.md
diff --git a/app/example/mikroe_dcmotor3_tb6549fg/mikroe_dcmotor3_tb6549fg.slcp b/app/example/mikroe_dcmotor3_tb6549fg/mikroe_dcmotor3_tb6549fg.slcp
index fb42d891..2843792b 100644
--- a/app/example/mikroe_dcmotor3_tb6549fg/mikroe_dcmotor3_tb6549fg.slcp
+++ b/app/example/mikroe_dcmotor3_tb6549fg/mikroe_dcmotor3_tb6549fg.slcp
@@ -35,7 +35,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_dcmotor3_tb6549fg/create_example.png
- path: ../../documentation/example/mikroe_dcmotor3_tb6549fg/hardware_connection.png
diff --git a/app/example/mikroe_e_paper_154_inch/app.c b/app/example/mikroe_e_paper_154_inch/app.c
new file mode 100644
index 00000000..ecc02586
--- /dev/null
+++ b/app/example/mikroe_e_paper_154_inch/app.c
@@ -0,0 +1,103 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+#include
+#include "sl_spidrv_instances.h"
+#include "mikroe_e_paper_154_inch_config.h"
+#include "glib.h"
+#include "mikroe_e_paper_154_inch.h"
+
+const char *str1 = "SILICON LABS";
+const char *str2 = "APPLICATION EXAMPLES";
+static glib_context_t g_context;
+
+const uint8_t EINK154_LUT_TABLE[30] =
+{
+ 0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22,
+ 0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88,
+ 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51,
+ 0x35, 0x51, 0x51, 0x19, 0x01, 0x00
+};
+
+static const unsigned char silicon_labs_logo_96x35[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xe0, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x0f, 0x00, 0xc0, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0xc0, 0x1f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xe0, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xf0, 0x7f,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xf8, 0x7f,
+ 0x00, 0x80, 0x01, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x1f, 0x00, 0xfe, 0x7f,
+ 0x00, 0xe0, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff,
+ 0x00, 0x78, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff,
+ 0x00, 0x3c, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x7f,
+ 0x00, 0x3f, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f,
+ 0x80, 0x3f, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x3f,
+ 0xe0, 0x3f, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x3f,
+ 0xf0, 0x3f, 0x00, 0x00, 0x80, 0xff, 0x1f, 0x00, 0x00, 0x80, 0xff, 0x1f,
+ 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x80, 0xff, 0x0f,
+ 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xff, 0x07,
+ 0xfc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0xff, 0x01,
+ 0xfe, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xff, 0x00,
+ 0xfe, 0xff, 0xff, 0x1f, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0x80, 0x3f, 0x00,
+ 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xc0, 0x0f, 0x00,
+ 0xfe, 0x0f, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x00, 0xe0, 0x03, 0x00,
+ 0xfe, 0x03, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x03, 0x00, 0xf0, 0x00, 0x00,
+ 0xfe, 0x01, 0x80, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x38, 0x00, 0x00,
+ 0xfc, 0x00, 0x80, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x0e, 0x00, 0x00,
+ 0xfc, 0x00, 0x80, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x80, 0x01, 0x00, 0x00,
+ 0xf0, 0x00, 0x80, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe0, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0xe0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+void app_init(void)
+{
+ glib_init(&g_context);
+ g_context.wrap = false;
+ g_context.text_color = E_PAPER_SCREEN_COLOR_BLACK;
+
+ mikroe_e_paper_154_inch_init(sl_spidrv_mikroe_handle);
+ mikroe_e_paper_154_inch_start_config();
+ mikroe_e_paper_154_inch_set_lut(EINK154_LUT_TABLE, 30);
+
+ glib_fill(&g_context, E_PAPER_SCREEN_COLOR_WHITE);
+ glib_draw_xbitmap(&g_context,
+ 52, 82, silicon_labs_logo_96x35,
+ 96, 35, EINK154_SCREEN_COLOR_BLACK);
+ glib_draw_string(&g_context, str1,
+ (MIKROE_E_PAPER_WIDTH - strlen(str1) * 6 + 1) / 2, 140);
+ glib_draw_string(&g_context, str2,
+ (MIKROE_E_PAPER_WIDTH - strlen(str2) * 6 + 1) / 2, 160);
+ glib_update_display();
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+}
diff --git a/app/example/mikroe_e_paper_154_inch/app.h b/app/example/mikroe_e_paper_154_inch/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_e_paper_154_inch/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_e_paper_154_inch/main.c b/app/example/mikroe_e_paper_154_inch/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_e_paper_154_inch/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_e_paper_154_inch/mikroe_e_paper_154_inch.slcp b/app/example/mikroe_e_paper_154_inch/mikroe_e_paper_154_inch.slcp
new file mode 100644
index 00000000..98081349
--- /dev/null
+++ b/app/example/mikroe_e_paper_154_inch/mikroe_e_paper_154_inch.slcp
@@ -0,0 +1,49 @@
+# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file.
+project_name: mikroe_e_paper_display
+label: Third Party Hardware Drivers - E-Paper Display 1,54" 200x200 dots (Mikroe)
+description: |
+ This example project shows an example for E-Paper Display 1,54" 200x200 dots driver integration.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_e_paper_154_inch/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: device_init
+- id: spidrv
+ instance: [mikroe]
+- id: mikroe_epaper_display_154_inch
+ from: third_party_hw_drivers
+- id: services_oled_glib
+ from: third_party_hw_drivers
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/mikroe_e_paper_154_inch/image/hardware_connection.png
+ directory: image
+ - path: ../../documentation/example/mikroe_e_paper_154_inch/image/create_example.png
+ directory: image
+ - path: ../../documentation/example/mikroe_e_paper_154_inch/image/result.png
+ directory: image
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_environment2_sht40_sgp40/mikroe_environment2.slcp b/app/example/mikroe_environment2_sht40_sgp40/mikroe_environment2.slcp
index 915b2b35..ef927e89 100644
--- a/app/example/mikroe_environment2_sht40_sgp40/mikroe_environment2.slcp
+++ b/app/example/mikroe_environment2_sht40_sgp40/mikroe_environment2.slcp
@@ -41,7 +41,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_environment2_sht40_sgp40/create_example.png
- path: ../../documentation/example/mikroe_environment2_sht40_sgp40/hardware_connection.png
diff --git a/app/example/mikroe_eth_wiz_w5500/mikroe_eth_wiz_w5500.slcp b/app/example/mikroe_eth_wiz_w5500/mikroe_eth_wiz_w5500.slcp
index abef82f3..d5359698 100644
--- a/app/example/mikroe_eth_wiz_w5500/mikroe_eth_wiz_w5500.slcp
+++ b/app/example/mikroe_eth_wiz_w5500/mikroe_eth_wiz_w5500.slcp
@@ -40,7 +40,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_eth_wiz_w5500/board.png
- path: ../../documentation/example/mikroe_eth_wiz_w5500/create_example.png
diff --git a/app/example/mikroe_fingerprint2_a172mrq/mikroe_fingerprint2_a172mrq.slcp b/app/example/mikroe_fingerprint2_a172mrq/mikroe_fingerprint2_a172mrq.slcp
index aabeb656..05b3ef4d 100644
--- a/app/example/mikroe_fingerprint2_a172mrq/mikroe_fingerprint2_a172mrq.slcp
+++ b/app/example/mikroe_fingerprint2_a172mrq/mikroe_fingerprint2_a172mrq.slcp
@@ -39,7 +39,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_fingerprint2_a172mrq/hardware_connection.png
- path: ../../documentation/example/mikroe_fingerprint2_a172mrq/create_example.png
diff --git a/app/example/mikroe_gpsclick_lea6s/mikroe_gps_click_lea6s.slcp b/app/example/mikroe_gpsclick_lea6s/mikroe_gps_click_lea6s.slcp
index 11ccb63b..bda1db99 100644
--- a/app/example/mikroe_gpsclick_lea6s/mikroe_gps_click_lea6s.slcp
+++ b/app/example/mikroe_gpsclick_lea6s/mikroe_gps_click_lea6s.slcp
@@ -51,7 +51,7 @@ toolchain_settings:
define:
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_gpsclick_lea6s/create_example.png
- path: ../../documentation/example/mikroe_gpsclick_lea6s/hardware_connection.png
diff --git a/app/example/mikroe_heartrate2_maxm86161/mikroe_heartrate2_maxm86161.slcp b/app/example/mikroe_heartrate2_maxm86161/mikroe_heartrate2_maxm86161.slcp
index e56c7f21..80c1c213 100644
--- a/app/example/mikroe_heartrate2_maxm86161/mikroe_heartrate2_maxm86161.slcp
+++ b/app/example/mikroe_heartrate2_maxm86161/mikroe_heartrate2_maxm86161.slcp
@@ -39,7 +39,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_heartrate2_maxm86161/create_example.png
- path: ../../documentation/example/mikroe_heartrate2_maxm86161/hardware_connection.png
diff --git a/app/example/mikroe_heartrate4_max30101/mikroe_heartrate4_max30101.slcp b/app/example/mikroe_heartrate4_max30101/mikroe_heartrate4_max30101.slcp
index fc695225..ef7d57bc 100644
--- a/app/example/mikroe_heartrate4_max30101/mikroe_heartrate4_max30101.slcp
+++ b/app/example/mikroe_heartrate4_max30101/mikroe_heartrate4_max30101.slcp
@@ -46,7 +46,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
ui_hints:
highlight:
- path: README.md
diff --git a/app/example/mikroe_irthermo3_mlx90632/mikroe_irthermo3_mlx90632.slcp b/app/example/mikroe_irthermo3_mlx90632/mikroe_irthermo3_mlx90632.slcp
index b54d29a5..ef39c285 100644
--- a/app/example/mikroe_irthermo3_mlx90632/mikroe_irthermo3_mlx90632.slcp
+++ b/app/example/mikroe_irthermo3_mlx90632/mikroe_irthermo3_mlx90632.slcp
@@ -45,7 +45,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
ui_hints:
highlight:
- path: README.md
diff --git a/app/example/mikroe_lte_iot2_bg96/app.c b/app/example/mikroe_lte_iot2_bg96/app.c
new file mode 100644
index 00000000..6efbbbf0
--- /dev/null
+++ b/app/example/mikroe_lte_iot2_bg96/app.c
@@ -0,0 +1,47 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+#include "app_log.h"
+#include "sl_sleeptimer.h"
+#include
+#include
+#include "at_parser_events.h"
+#include "mikroe_bg96.h"
+#include "app_iostream_cli.h"
+
+void app_init(void)
+{
+ app_log_iostream_set(sl_iostream_vcom_handle);
+ app_log("Hello World LTE IoT 2 Click !!!\r\n");
+ bg96_nb_init();
+ app_log("BG96 init done !!!\r\n");
+ app_log("Type your command to execute the function !!!\r\n");
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ app_iostream_cli_process_action();
+ at_parser_process();
+ at_platform_process();
+ at_event_process();
+}
diff --git a/app/example/mikroe_lte_iot2_bg96/app.h b/app/example/mikroe_lte_iot2_bg96/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_lte_iot2_bg96/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_lte_iot2_bg96/app_iostream_cli.c b/app/example/mikroe_lte_iot2_bg96/app_iostream_cli.c
new file mode 100644
index 00000000..e553d211
--- /dev/null
+++ b/app/example/mikroe_lte_iot2_bg96/app_iostream_cli.c
@@ -0,0 +1,1192 @@
+/***************************************************************************//**
+ * @file app_iostream_cli.c
+ * @brief source of simple CLI
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#include
+#include
+#include "em_chip.h"
+#include "sl_iostream.h"
+#include "sl_iostream_init_instances.h"
+#include "sl_iostream_handles.h"
+#include "at_parser_core.h"
+#include "app_iostream_cli.h"
+#include "at_parser_events.h"
+#include "app_log.h"
+#include "mikroe_bg96.h"
+#include "sl_string.h"
+#include "stdlib.h"
+
+/*******************************************************************************
+ ******************************* MACROS ************************************
+ ******************************************************************************/
+#ifndef BUFSIZE
+#define BUFSIZE 80
+#endif
+
+/* AT+QGPSLOC Acquire Positioning Information
+ * Response: "+QGPSLOC: ,,,,,,
+ * ,,,,"
+ *
+ */
+typedef enum {
+ gpsloc_element_UTC_time_e = 1,
+ gpsloc_element_latitude_e,
+ gpsloc_element_longitude_e,
+ gpsloc_element_hdop_e,
+ gpsloc_element_altitude_e,
+ gpsloc_element_fix_e,
+ gpsloc_element_cog_e,
+ gpsloc_element_spkm_e,
+ gpsloc_element_spkn_e,
+ gpsloc_element_date_e,
+ gpsloc_element_nsat_e,
+}bg96_gnssloc_response_elements_t;
+
+/*******************************************************************************
+ *************** STATIC FUNCTION DECLARATIONS ******************************
+ ******************************************************************************/
+static void app_parser(uint8_t *buf);
+static void wakeup(void);
+static void sleep(void);
+static void infor(void);
+static void imei(void);
+static void textmode(void);
+static void pdumode(void);
+static void set_gsm(void);
+static void set_service_domain(void);
+static void sms_text(void);
+static void sms_pdu(void);
+static void sim_apn(void);
+static void ip(void);
+static void net_reg(void);
+static void open(void);
+static void send(void);
+static void close(void);
+static void cops(void);
+static void receive(void);
+static void gps_start(void);
+static void gps_location(void);
+static void gps_stop(void);
+static void open_server(void);
+static void close_server(void);
+
+static void wakeup_handler(void *handler_data);
+static void sleep_handler(void *handler_data);
+static void infor_handler(void *handler_data);
+static void imei_handler(void *handler_data);
+static void settextmode_handler(void *handler_data);
+static void setpdumode_handler(void *handler_data);
+static void set_gsm_handler(void *handler_data);
+static void set_service_domain_handler(void *handler_data);
+static void sms_text_handler(void *handler_data);
+static void sms_pdu_handler(void *handler_data);
+static void sim_apn_handler(void *handler_data);
+static void ip_handler(void *handler_data);
+static void net_reg_handler(void *handler_data);
+static void open_handler(void *handler_data);
+static void close_handler(void *handler_data);
+static void send_handler(void *handler_data);
+static void recv_handler(void *handler_data);
+static void cops_handler(void *handler_data);
+static void stop_gnss_handler(void *handler_data);
+static void get_position_handler(void *handler_data);
+static void start_gnss_handler(void *handler_data);
+static sl_status_t bg96_gpsloc_generic_parser(uint8_t *input_string,
+ uint8_t *parser_buf,
+ bg96_gnssloc_response_elements_t element);
+
+/*******************************************************************************
+ ************************** GLOBAL VAAIBLES *********************************
+ ******************************************************************************/
+static uint8_t buffer[BUFSIZE];
+
+/**************************************************************************//**
+ * @brief
+ * Command and handler definitions for the CLI.
+ *
+ *****************************************************************************/
+static cli_cmd_t cli_cmds[] = {
+ { "wakeup", wakeup },
+ { "sleep", sleep },
+ { "imei", imei },
+ { "infor", infor },
+ { "gsm", set_gsm },
+ { "service", set_service_domain },
+ { "textmode", textmode },
+ { "pdumode", pdumode },
+ { "smstext", sms_text },
+ { "smspdu", sms_pdu },
+ { "simapn", sim_apn },
+ { "ip", ip },
+ { "netreg", net_reg },
+ { "open", open },
+ { "send", send },
+ { "close", close },
+ { "cops", cops },
+ { "recv", receive },
+ { "gpsstart", gps_start },
+ { "location", gps_location },
+ { "gpsstop", gps_stop },
+ { "opens", open_server },
+ { "closes", close_server },
+};
+static uint8_t cli_cmd_size = sizeof(cli_cmds) / sizeof(cli_cmds[0]);
+
+at_scheduler_status_t output_object = {
+ SL_STATUS_NOT_INITIALIZED,
+ 0, ""
+};
+
+/**************************************************************************//**
+ * @brief
+ * App layer process function.
+ * This function SHALL be called periodically in the main loop.
+ *
+ *****************************************************************************/
+void app_iostream_cli_process_action(void)
+{
+ char c = 0;
+ static uint8_t index = 0;
+ static bool start_cli = false;
+
+ /* Retrieve characters, print local echo and full line back */
+ sl_iostream_getchar(sl_iostream_vcom_handle, &c);
+ if (c > 0) {
+ if ((c == '\r') || (c == '\n')) {
+ sl_iostream_putchar(sl_iostream_vcom_handle, '\r');
+ sl_iostream_putchar(sl_iostream_vcom_handle, '\n');
+ buffer[index] = '\0';
+ app_parser(buffer);
+ index = 0;
+ start_cli = false;
+ } else {
+ if (index < BUFSIZE - 1) {
+ buffer[index] = c;
+ index++;
+ }
+
+ if (start_cli == false) {
+ start_cli = true;
+ app_log("[>>>] ");
+ }
+
+ /* Local echo */
+ sl_iostream_putchar(sl_iostream_vcom_handle, c);
+ }
+ }
+}
+
+/**************************************************************************//**
+ * @brief
+ * App lacer incoming command parser function.
+ *
+ * @param[in] buf
+ * Pointer to the buffer which contains the input command.
+ *
+ *****************************************************************************/
+static void app_parser(uint8_t *buf)
+{
+ uint8_t i;
+
+ for (i = 0; i < cli_cmd_size; i++) {
+ if (!strncmp((const char *) cli_cmds[i].cmd, (const char *) buf,
+ CLI_CMD_LENGTH)) {
+ cli_cmds[i].handler();
+ return;
+ }
+ }
+ app_log("Can't recognize command!\r\n");
+}
+
+/**************************************************************************//**
+* Command handler functions
+******************************************************************************/
+
+/***************************************************************************//**
+ * @brief
+ * Wake up function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void wakeup(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_wake_up(&output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK,
+ wakeup_handler, (void *) &output_object);
+ app_log("Waking up device!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Wake up handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void wakeup_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+ if (l_output->error_code) {
+ app_log("Error while waking up: %d\r\n", l_output->error_code);
+ } else {
+ app_log("Device is up!\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Sleep function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void sleep(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_sleep(&output_object);
+ at_listen_event((uint8_t *) &output_object.status,
+ SL_STATUS_OK,
+ sleep_handler,
+ (void *) &output_object);
+ app_log("Put the device to sleep!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Sleep handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void sleep_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+ if (l_output->error_code) {
+ app_log("Error while putting to sleep: %d\r\n", l_output->error_code);
+ } else {
+ app_log("Device went to sleep!\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get IMEI function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void imei(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_read_imei(&output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK, imei_handler,
+ (void *) &output_object);
+ app_log("Read IMEI command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get IMEI handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void imei_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while reading IMEI: %d\r\n", l_output->error_code);
+ } else {
+ app_log("IMEI: %s\r\n", l_output->response_data);
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get BG96 Module information function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void infor(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_read_infor(&output_object);
+ at_listen_event((uint8_t *) &output_object.status,
+ SL_STATUS_OK,
+ infor_handler,
+ (void *) &output_object);
+ app_log("Get Quectel BG96 module infor command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get BG96 Module information handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void infor_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while reading BG96 Infor: %d\r\n", l_output->error_code);
+ } else {
+ app_log("%s\r\n", l_output->response_data);
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Select TE Character Set to GSM function. Call this function before sending
+ * sms. Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void set_gsm(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_set_te_gsm(&output_object);
+ at_listen_event((uint8_t *) &output_object.status,
+ SL_STATUS_OK,
+ set_gsm_handler,
+ (void *) &output_object);
+ app_log("Select TE Character Set to GSM command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Select TE Character Set to GSM handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void set_gsm_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while set te character set GSM: %d\r\n",
+ l_output->error_code);
+ } else {
+ app_log("Set GSM OK\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Configure the service domain of UE function
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void set_service_domain(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_config_service_domain(&output_object, service_domain_type_CS_and_PS_e);
+ at_listen_event((uint8_t *) &output_object.status,
+ SL_STATUS_OK, set_service_domain_handler,
+ (void *) &output_object);
+ app_log("Set the service domain CS_and_PS command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Configure the service domain of UE handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void set_service_domain_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while configure the service domain of UE: %d\r\n",
+ l_output->error_code);
+ } else {
+ app_log("Configure the service domain OK\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set BG96 to Text Mode function. Call this function before sending sms
+ * text.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void textmode(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_set_sms_mode(&output_object, set_sms_mode_text);
+ at_listen_event((uint8_t *) &output_object.status,
+ SL_STATUS_OK,
+ settextmode_handler,
+ (void *) &output_object);
+ app_log("Set BG96 to text mode command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set BG96 to Text Mode handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void settextmode_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while set SMS text mode %d\r\n", l_output->error_code);
+ } else {
+ app_log("Set SMS text mode OK\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set BG96 to PDU Mode function. Call this function before sending sms pdu.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void pdumode(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_set_sms_mode(&output_object, set_sms_mode_pdu);
+ at_listen_event((uint8_t *) &output_object.status,
+ SL_STATUS_OK,
+ setpdumode_handler,
+ (void *) &output_object);
+ app_log("Set BG96 to pdu mode command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set BG96 to PDU Mode handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void setpdumode_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while set SMS pdu mode %d\r\n", l_output->error_code);
+ } else {
+ app_log("Set SMS pdu mode OK\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Send SMS Text function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void sms_text(void)
+{
+ bg96_sms_text_t sms_text = { "+84379228377", \
+ "Hello World - LTE IoT 2 Click Board !!! - (sms text mode)" };
+
+ at_parser_init_output_object(&output_object);
+ bg96_send_sms_text(&output_object, &sms_text);
+
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK,
+ sms_text_handler, (void *) &output_object);
+ app_log("SMS text command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Send SMS Text handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void sms_text_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while send sms text: %d\r\n",
+ l_output->error_code);
+ } else {
+ app_log("Send sms text mode ok, response data: %s\r\n",
+ l_output->response_data);
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Send SMS PDU function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void sms_pdu(void)
+{
+ bg96_sms_pdu_t sms_pdu = {
+ "+84980200030",
+ "+84379228377",
+ "Hello World - LTE IoT 2 Click Board !!! - (sms pdu mode)"
+ };
+
+ at_parser_init_output_object(&output_object);
+ bg96_send_sms_pdu(&output_object, &sms_pdu);
+
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK,
+ sms_pdu_handler, (void *) &output_object);
+ app_log("SMS pdu command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Send SMS PDU handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void sms_pdu_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while send sms pdu: %d\r\n",
+ l_output->error_code);
+ } else {
+ app_log("Send sms text mode ok, response data: %s\r\n",
+ l_output->response_data);
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set SIM APN function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void sim_apn(void)
+{
+ uint8_t sim_apn[30] = "v-internet";
+
+ at_parser_init_output_object(&output_object);
+ bg96_set_sim_apn(&output_object, (uint8_t *)sim_apn);
+
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK,
+ sim_apn_handler, (void *) &output_object);
+ app_log("Set SIM APN command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Set SIM APN handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void sim_apn_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while set sim apn: %d\r\n", l_output->error_code);
+ } else {
+ app_log("Set SIM APN ok\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get IO address function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void ip(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_read_ip(&output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK, ip_handler,
+ (void *) &output_object);
+ app_log("Read IP command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get IP address handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void ip_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+ if (l_output->error_code) {
+ app_log("Error while reading IP: %d\r\n%s\r\n", l_output->error_code,
+ l_output->response_data);
+ } else {
+ app_log("IP address: %s\r\n", l_output->response_data);
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Network registration function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void net_reg(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_network_registration(&output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK,
+ net_reg_handler, (void *) &output_object);
+ app_log("Network registration started!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Network registration handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void net_reg_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+ if (l_output->error_code) {
+ app_log("Network registration error: %d\r\n%s\r\n", l_output->error_code,
+ l_output->response_data);
+ } else {
+ app_log("Network registration done!\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Open client connection function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void open(void)
+{
+ bg96_nb_connection_t connection = {
+ 0,
+ 9999,
+ "TCP",
+ (uint8_t *) "cloudsocket.hologram.io"
+ };
+
+ at_parser_init_output_object(&output_object);
+ bg96_nb_open_connection(&connection, &output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK, open_handler,
+ (void *) &output_object);
+ app_log("Open command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Open client connection handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void open_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Network open error: %d\r\n", (int) l_output->error_code);
+ } else {
+ app_log("Network opened.\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Open server connection function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void open_server(void)
+{
+ bg96_nb_connection_t connection = {
+ 0,
+ 2020,
+ "TCP LISTENER",
+ (uint8_t *) "127.0.0.1"
+ };
+
+ at_parser_init_output_object(&output_object);
+ bg96_nb_open_connection(&connection, &output_object);
+ app_log("Open server command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Close server connection function.
+ * Result will be available in the global output_object.
+ ******************************************************************************/
+static void close_server(void)
+{
+ bg96_nb_connection_t connection = {
+ 11,
+ 2020,
+ "TCP LISTENER",
+ (uint8_t *) "127.0.0.1"
+ };
+
+ at_parser_init_output_object(&output_object);
+ bg96_nb_close_connection(&connection, &output_object);
+ app_log("Open server command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Send data on an opened channel.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void send(void)
+{
+ bg96_nb_connection_t connection = {
+ 0,
+ 9999,
+ "TCP",
+ (uint8_t *) "cloudsocket.hologram.io"
+ };
+ uint8_t data_to_send[] =
+ "{\"k\":\"Tm}hswZ8\",\"d\":\"Hello Silabs!\",\"t\":\"my_topic\"}";
+
+ at_parser_init_output_object(&output_object);
+ bg96_nb_send_data(&connection, data_to_send, &output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK, send_handler,
+ (void *) &output_object);
+ app_log("Data has been sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Send data handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void send_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+ app_log("Send response received! Error: %d Data: %s\r\n",
+ l_output->error_code,
+ l_output->response_data);
+}
+
+/***************************************************************************//**
+ * @brief
+ * Close client connection function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void close(void)
+{
+ bg96_nb_connection_t connection = {
+ 0,
+ 9999,
+ "TCP",
+ (uint8_t *) "cloudsocket.hologram.io"
+ };
+
+ at_parser_init_output_object(&output_object);
+ bg96_nb_close_connection(&connection, &output_object);
+ at_listen_event((uint8_t *) &output_object.status,
+ SL_STATUS_OK,
+ close_handler,
+ (void *) &output_object);
+ app_log("Close command sent!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Close client connection handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void close_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Network close error: %d\r\n %s\r\n", l_output->error_code,
+ l_output->response_data);
+ } else {
+ app_log("Network closed\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get actual operator function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void cops(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_get_operator(&output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK, cops_handler,
+ (void *) &output_object);
+ app_log("Getting operator!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get actual operator handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void cops_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while getting operator: %d\r\n %s\r\n", l_output->error_code,
+ l_output->response_data);
+ } else {
+ app_log("Actual operator: %s\r\n", l_output->response_data);
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Receive data function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void receive(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_nb_receive_data(&output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK, recv_handler,
+ (void *) &output_object);
+ app_log("Receiving data!\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Receive data handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void recv_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+ if (l_output->error_code) {
+ app_log("Error while receiving data: %d\r\n %s\r\n", l_output->error_code,
+ l_output->response_data);
+ } else {
+ app_log("Received data: %s\r\n", l_output->response_data);
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * GNSS start function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void gps_start(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_gnss_start(&output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK,
+ start_gnss_handler, (void *) &output_object);
+ app_log("GNSS start command sent.\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Start GNSS handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void start_gnss_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while starting GNSS: %d\r\n", l_output->error_code);
+ } else {
+ app_log("GNSS started.\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * GNSS get location function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void gps_location(void)
+{
+ at_parser_init_output_object(&output_object);
+ bg96_gnss_get_position(&output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK,
+ get_position_handler, (void *) &output_object);
+ app_log("GNSS position command sent.\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Get GNSS location handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ * +QGPSLOC: ,,,,,,,
+ * ,,,
+ ******************************************************************************/
+static void get_position_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while getting position: %d\r\n %s\r\n", l_output->error_code,
+ l_output->response_data);
+ } else {
+ app_log("GPS location raw response data: %s\r\n", l_output->response_data);
+
+ uint8_t element_buf[200] = { 0 };
+ sl_status_t stt = bg96_gpsloc_generic_parser(l_output->response_data,
+ element_buf,
+ gpsloc_element_latitude_e);
+
+ if ((sl_strlen((char *) element_buf) > 0) && (SL_STATUS_OK == stt)) {
+ /*
+ * Latitude ranges between -90 and 90 degrees.
+ * Longitude ranges between -180 and 180 degrees.
+ *
+ * Convert to degree calculation example:
+ * Latitude: [N] 2451.71 is 24 degrees north latitude and 51.71
+ * minutes.
+ * Convert the points to degrees 51.71 / 60 = 0.86183.
+ * The actual Google Map corresponds to 24 + 0.86183 = +24.86183.
+ * Longitude: [E] 12100.99 is 121 degrees east long and 0.99 points.
+ * Convert the points to degrees 0.99 / 60 = 0.0165.
+ * The actual Google Map is 121 + 0.0165 = +121.0165.
+ * Combine the converted latitude and longitude data into
+ * (+24.86183, +121.0165) and enter the field of Google Map to find the
+ * actual corresponding location.
+ */
+
+ uint8_t latitude_int[10];
+ uint8_t latitude_decimal[10];
+ uint8_t longitude_int[10];
+ uint8_t longitude_decimal[10];
+
+ // latitude_int = 2 character
+ memcpy((void *)latitude_int, (const void *)element_buf, 2);
+ // Ignore addition one character = 'N' or 'S'
+ memcpy((void *)latitude_decimal,
+ (const void *)(element_buf + 2),
+ strlen((const char *)element_buf) - 3);
+ double latitude = (atof((const char *)latitude_int)
+ + (atof((const char *)(latitude_decimal)) / 60.0));
+ app_log("Latitude: %.6f\r\n", latitude);
+ memset(element_buf, 0, sizeof(element_buf));
+
+ bg96_gpsloc_generic_parser(l_output->response_data,
+ element_buf,
+ gpsloc_element_longitude_e);
+ // longitude_int = 3 character
+ memcpy((void *)longitude_int, (const void *)element_buf, 3);
+ // Ignore addition one character = 'E' or 'W'
+ memcpy((void *)longitude_decimal,
+ (const void *) (element_buf + 3),
+ strlen((const char *)element_buf) - 4);
+ double longtitude = (atof((const char *)longitude_int)
+ + (atof((const char *)(longitude_decimal))
+ / 60.0));
+ app_log("Longitude: %.6f\r\n", longtitude);
+ memset(element_buf, 0, sizeof(element_buf));
+
+ bg96_gpsloc_generic_parser(l_output->response_data,
+ element_buf,
+ gpsloc_element_altitude_e);
+ app_log("Altitude: %sM\r\n", element_buf);
+
+ bg96_gpsloc_generic_parser(l_output->response_data,
+ element_buf,
+ gpsloc_element_UTC_time_e);
+ uint8_t hour[3] = { 0 };
+ uint8_t minuste[3] = { 0 };
+ uint8_t seconds[3] = { 0 };
+ memcpy((void *)hour, (const void *)element_buf, 2);
+ memcpy((void *)minuste, (const void *)element_buf + 2, 2);
+ memcpy((void *)seconds, (const void *)element_buf + 4, 2);
+
+ app_log("Time UTC: %sh:%sm:%ss\r\n", hour, minuste, seconds);
+
+ bg96_gpsloc_generic_parser(l_output->response_data,
+ element_buf,
+ gpsloc_element_date_e);
+ uint8_t day[3] = { 0 };
+ uint8_t month[3] = { 0 };
+ uint8_t year[3] = { 0 };
+ memcpy((void *)day, (const void *)element_buf, 2);
+ memcpy((void *)month, (const void *)element_buf + 2, 2);
+ memcpy((void *)year, (const void *)element_buf + 4, 2);
+
+ app_log("Date: %s/%s/20%s\r\n", day, month, year);
+ }
+ }
+}
+
+sl_status_t bg96_gpsloc_generic_parser(uint8_t *input_string,
+ uint8_t *parser_buf,
+ bg96_gnssloc_response_elements_t element)
+{
+ uint8_t rsp_buf[200];
+ uint8_t element_cnt = 0;
+ uint8_t *start_rsp;
+ uint8_t *element_start;
+ uint8_t *element_end;
+
+ start_rsp = (uint8_t *)strstr((const char *) input_string,
+ (const char *)"+QGPSLOC: ");
+
+ if ((start_rsp != 0)) {
+ memset(rsp_buf, 0, 200);
+ sl_strcpy_s((char *)rsp_buf, 200, (const char *) start_rsp);
+ element_start = rsp_buf + strlen((const char *)"+QGPSLOC: ");
+
+ do
+ {
+ if (element_cnt != 0) {
+ element_start =
+ (uint8_t *)strstr((const char *) element_start, (const char *)",");
+ if (element_start != 0) {
+ element_start++;
+ }
+ }
+ element_cnt++;
+ } while (element_cnt < element);
+
+ element_end = (uint8_t *)strstr((const char *) element_start,
+ (const char *)",");
+
+ if ((element_start != 0) && (element_end != 0)) {
+ strncpy((char *) parser_buf,
+ (const char *)element_start,
+ element_end - element_start);
+ }
+ } else {
+ return SL_STATUS_FAIL;
+ }
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * GNSS stop listening function.
+ * Result will be available in the global output_object.
+ *
+ ******************************************************************************/
+static void gps_stop(void)
+{
+ at_parser_init_output_object(&output_object);
+ at_listen_event((uint8_t *) &output_object.status, SL_STATUS_OK,
+ stop_gnss_handler, (void *) &output_object);
+ bg96_gnss_stop(&output_object);
+ app_log("GNSS stop command sent.\r\n");
+}
+
+/***************************************************************************//**
+ * @brief
+ * Stop GNSS handler function.
+ *
+ * @param[in] handler_data
+ * Data sent by the event handler.
+ * Currently handler_data is a pointer to an at_scheduler_status_t.
+ *
+ ******************************************************************************/
+static void stop_gnss_handler(void *handler_data)
+{
+ at_scheduler_status_t *l_output = (at_scheduler_status_t *) handler_data;
+
+ if (l_output->error_code) {
+ app_log("Error while stopping GNSS: %d\r\n", l_output->error_code);
+ } else {
+ app_log("GNSS stopped.\r\n");
+ }
+}
diff --git a/app/example/mikroe_lte_iot2_bg96/app_iostream_cli.h b/app/example/mikroe_lte_iot2_bg96/app_iostream_cli.h
new file mode 100644
index 00000000..3d1c3377
--- /dev/null
+++ b/app/example/mikroe_lte_iot2_bg96/app_iostream_cli.h
@@ -0,0 +1,60 @@
+/***************************************************************************//**
+ * @file app_iostream_cli.h
+ * @brief header file for simple app CLI
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+
+#ifndef APP_IOSTREAM_USART_H
+#define APP_IOSTREAM_USART_H
+
+#include
+
+/*******************************************************************************
+ ******************************** MACROS ***********************************
+ ******************************************************************************/
+#define CLI_CMD_LENGTH 10
+
+/*******************************************************************************
+ ************************** STRUCTURES *******************************
+ ******************************************************************************/
+typedef struct {
+ uint8_t cmd[CLI_CMD_LENGTH];
+ void (*handler)();
+} cli_cmd_t;
+
+/***************************************************************************//**
+ * @brief
+ * IOstream usart ticking function.
+ ******************************************************************************/
+void app_iostream_cli_process_action(void);
+
+#endif // APP_IOSTREAM_USART_H
diff --git a/app/example/mikroe_lte_iot2_bg96/main.c b/app/example/mikroe_lte_iot2_bg96/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_lte_iot2_bg96/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_lte_iot2_bg96/mikroe_lte_iot2_bg96.slcp b/app/example/mikroe_lte_iot2_bg96/mikroe_lte_iot2_bg96.slcp
new file mode 100644
index 00000000..14e278d8
--- /dev/null
+++ b/app/example/mikroe_lte_iot2_bg96/mikroe_lte_iot2_bg96.slcp
@@ -0,0 +1,68 @@
+project_name: mikroe_lte_iot2_bg96
+label: Third Party Hardware Drivers - BG96 - LTE IoT 2 Click (Mikroe)
+description: |
+ This example project shows an example for Third Party Hardware Drivers - BG96 - LTE IoT 2 Click (Mikroe) integration.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_lte_iot2_bg96/README.md
+source:
+- path: app.c
+- path: main.c
+- path: app_iostream_cli.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+ - path: app_iostream_cli.h
+config_file:
+component:
+- id: sl_system
+- id: app_log
+- id: mikroe_lte_iot2
+ from: third_party_hw_drivers
+- id: iostream_eusart
+ instance:
+ - vcom
+- id: iostream_usart
+ instance:
+ - bg96
+- id: device_init
+- id: simple_timer
+configuration:
+toolchain_settings:
+ - option: gcc_linker_option
+ value: "-u _printf_float"
+define:
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/mikroe_lte_iot2_bg96/image/create_example.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_1.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_2.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_lte_iot2_bg96/image/hardware_connection_3.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_lte_iot2_bg96/image/log.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_lte_iot2_bg96/image/sms_receive.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_lte_iot2_bg96/image/layer.drawio.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_lte_iot2_bg96/image/gps_log.png
+ directory: "image"
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_microsd/app.c b/app/example/mikroe_microsd/app.c
new file mode 100644
index 00000000..36aedc83
--- /dev/null
+++ b/app/example/mikroe_microsd/app.c
@@ -0,0 +1,160 @@
+/***************************************************************************//**
+ * @file app.c
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ ********************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Experimental Quality
+ * This code has not been formally tested and is provided as-is. It is not
+ * suitable for production environments. In addition, this code will not be
+ * maintained and there may be no bug maintenance planned for these resources.
+ * Silicon Labs may update projects from time to time.
+ ******************************************************************************/
+#include "string.h"
+
+#include "diskio.h"
+#include "ff.h"
+
+#include "sl_spidrv_instances.h"
+#include "sl_sdc_sd_card.h"
+
+#include "app_log.h"
+#include "app_assert.h"
+
+#if !FF_FS_NORTC && !FF_FS_READONLY
+#include "sl_sleeptimer.h"
+#endif
+
+static const char str[] = "Silabs SD Card I/O Example via SPI!\r\n";
+static const char *fst[] = { "", "FAT12", "FAT16", "FAT32", "exFAT" };
+
+BYTE f_work[FF_MAX_SS]; // Work area (larger is better for processing time)
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+ FATFS fs;
+ FATFS *pfs;
+ FIL fil;
+ DWORD fre_clust;
+ FRESULT ret_code;
+ UINT bw;
+ UINT br;
+
+#if !FF_FS_NORTC && !FF_FS_READONLY
+ DWORD time_data;
+ sl_status_t sc;
+ sl_sleeptimer_date_t date = {
+ .year = 122,
+ .month = 2,
+ .month_day = 1,
+ .hour = 10,
+ .min = 30,
+ .sec = 0,
+ };
+
+ sc = sl_sleeptimer_set_datetime(&date);
+ app_assert_status(sc);
+
+ time_data = get_fattime();
+ app_log("\nCurrent time is %lu/%lu/%lu %2lu:%02lu:%02lu.\n\n",
+ (time_data >> 25) + 1980,
+ (time_data >> 21) & 0x0f,
+ (time_data >> 16) & 0x1f,
+ (time_data >> 11) & 0x1f,
+ (time_data >> 5) & 0x3f,
+ (time_data << 1) & 0x1f);
+#endif
+
+ sd_card_spi_init(sl_spidrv_mikroe_handle);
+
+ // Give a work area to the default drive
+ ret_code = f_mount(&fs, "", 0);
+ app_assert_status(ret_code);
+
+ // Show logical drive status
+ ret_code = f_getfree("", &fre_clust, &pfs);
+ app_assert_status(ret_code);
+ app_log("-------------- Volume status --------------\n\r");
+ app_log(("FAT type = %s\nBytes/Cluster = %lu\nNumber of FATs = %u\n"
+ "Root DIR entries = %u\nSectors/FAT = %lu\n"
+ "Number of clusters = %lu\nVolume start (lba) = %lu\n"
+ "FAT start (lba) = %lu\nDIR start (lba,clustor) = %lu\n"
+ "Data start (lba) = %lu\n%lu KiB total disk space.\n"
+ "%lu KiB available.\n\n"),
+ fst[pfs->fs_type],
+ (DWORD)pfs->csize * 512,
+ pfs->n_fats,
+ pfs->n_rootdir,
+ pfs->fsize,
+ pfs->n_fatent - 2,
+ (DWORD)pfs->volbase,
+ (DWORD)pfs->fatbase,
+ (DWORD)pfs->dirbase,
+ (DWORD)pfs->database,
+ (pfs->n_fatent - 2) * (pfs->csize / 2),
+ fre_clust * (pfs->csize / 2));
+
+ app_log("-------- Open file to write and read again ---------\n\r");
+ // Open file to write
+ ret_code = f_open(&fil, "hello.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
+ app_assert_status(ret_code);
+
+ // Write a message
+ ret_code = f_write(&fil, str, sizeof(str), &bw);
+ app_assert_status(ret_code);
+ app_log("Write a message to SD card success! Byte writen = %d\n\r", bw);
+
+ // Close file
+ ret_code = f_close(&fil);
+ app_assert_status(ret_code);
+
+ // Open file to read
+ ret_code = f_open(&fil, "hello.txt", FA_OPEN_EXISTING | FA_READ);
+ app_assert_status(ret_code);
+
+ // Read back the content and print on the console
+ ret_code = f_read(&fil, f_work, sizeof(f_work), &br);
+ app_assert_status(ret_code);
+ app_log("Read a message from SD card success! Byte read = %d\n\r", br);
+ app_log("Content: %s", f_work);
+
+ // Close file
+ ret_code = f_close(&fil);
+ app_assert_status(ret_code);
+
+ // Unmount SDCARD
+ (void)f_mount(NULL, "", 1);
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+}
diff --git a/app/example/mikroe_microsd/app.h b/app/example/mikroe_microsd/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_microsd/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_microsd/main.c b/app/example/mikroe_microsd/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_microsd/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_microsd/mikroe_microsd.slcp b/app/example/mikroe_microsd/mikroe_microsd.slcp
new file mode 100644
index 00000000..cd418586
--- /dev/null
+++ b/app/example/mikroe_microsd/mikroe_microsd.slcp
@@ -0,0 +1,64 @@
+# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file.
+project_name: mikroe_microsd
+label: Third Party Hardware Drivers - microSD Click (Mikroe)
+description: |
+ This example project shows an example for Mikroe microSD click board driver integration.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_microsd/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: app_log
+- id: app_assert
+- id: iostream_usart
+ instance: [vcom]
+- id: services_fatfs
+ from: third_party_hw_drivers
+- id: mikroe_microsd
+ from: third_party_hw_drivers
+- id: device_init
+- id: sleeptimer
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/mikroe_microsd/images/create_example.png
+ directory: images
+ - path: ../../documentation/example/mikroe_microsd/images/board.png
+ directory: images
+ - path: ../../documentation/example/mikroe_microsd/images/content_file.png
+ directory: images
+ - path: ../../documentation/example/mikroe_microsd/images/create_example.png
+ directory: images
+ - path: ../../documentation/example/mikroe_microsd/images/mikrobus.png
+ directory: images
+ - path: ../../documentation/example/mikroe_microsd/images/structure_overview.png
+ directory: images
+ - path: ../../documentation/example/mikroe_microsd/images/system_overview.png
+ directory: images
+ - path: ../../documentation/example/mikroe_microsd/images/testing.png
+ directory: images
+ - path: ../../documentation/example/mikroe_microsd/images/workflow.png
+ directory: images
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_nfc2_pn7150/app.c b/app/example/mikroe_nfc2_pn7150/app.c
new file mode 100644
index 00000000..6b0d8477
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150/app.c
@@ -0,0 +1,212 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#include
+#include "sl_i2cspm_instances.h"
+#include "sl_sleeptimer.h"
+#include "app_log.h"
+#include "mikroe_pn7150.h"
+
+#define NFC2_IRQ_STATE_LOW 0
+#define NFC2_IRQ_STATE_HIGH 1
+
+static mikroe_pn7150_control_packet_t ctrl_pck_data;
+
+/**
+ * @brief NFC 2 display packet function.
+ * @details This function displays data values.
+ */
+static void display_packet(mikroe_pn7150_control_packet_t *ctrl_pck);
+
+/**
+ * @brief NFC 2 display nfc data function.
+ * @details This function displays nfc data values.
+ */
+static void display_nfc_data(mikroe_pn7150_control_packet_t *ctrl_pck);
+
+/**
+ * @brief NFC 2 read nfc data function.
+ * @details This function reads nfc data and displays data.
+ */
+static void read_nfc_data(mikroe_pn7150_control_packet_t *ctrl_pck);
+
+/**
+ * @brief NFC 2 test antena function.
+ * @details This function tests antenna and displays data.
+ */
+static void test_antenna(mikroe_pn7150_control_packet_t *ctrl_pck);
+
+void app_init(void)
+{
+ app_log(" Application Init ");
+
+ if (SL_STATUS_OK != mikroe_pn7150_init(sl_i2cspm_mikroe)) {
+ app_log("> PN7150 - NFC 2 Click board driver init failed.\n");
+ }
+ sl_sleeptimer_delay_millisecond(100);
+
+ app_log(" HW Reset \r\n");
+ mikroe_pn7150_hw_reset();
+ sl_sleeptimer_delay_millisecond(100);
+
+ app_log("-----------------------\r\n");
+ app_log(" Reset and Init. Core \r\n");
+ mikroe_pn7150_cmd_core_reset();
+ sl_sleeptimer_delay_millisecond(100);
+
+ mikroe_pn7150_read_ctrl_packet_data(&ctrl_pck_data);
+ sl_sleeptimer_delay_millisecond(100);
+
+ mikroe_pn7150_cmd_core_init();
+ sl_sleeptimer_delay_millisecond(100);
+
+ mikroe_pn7150_read_ctrl_packet_data(&ctrl_pck_data);
+ sl_sleeptimer_delay_millisecond(100);
+ display_packet(&ctrl_pck_data);
+
+ while (mikroe_pn7150_check_irq() == NFC2_IRQ_STATE_HIGH) {}
+
+ app_log("-----------------------\r\n");
+ app_log(" Disabling Standby Mode \r\n");
+ mikroe_pn7150_cmd_disable_standby_mode();
+ sl_sleeptimer_delay_millisecond(100);
+
+ mikroe_pn7150_read_ctrl_packet_data(&ctrl_pck_data);
+ sl_sleeptimer_delay_millisecond(100);
+ display_packet(&ctrl_pck_data);
+
+ test_antenna(&ctrl_pck_data);
+
+ app_log("-----------------------\r\n");
+ app_log("Starting Test Procedure\r\n");
+ mikroe_pn7150_cmd_test_procedure();
+ sl_sleeptimer_delay_millisecond(100);
+
+ mikroe_pn7150_read_ctrl_packet_data(&ctrl_pck_data);
+ sl_sleeptimer_delay_millisecond(100);
+ display_packet(&ctrl_pck_data);
+
+ mikroe_pn7150_hw_reset();
+ sl_sleeptimer_delay_millisecond(100);
+
+ app_log("-----------------------\r\n");
+ app_log(" NFC Config. \r\n");
+ mikroe_pn7150_default_cfg(&ctrl_pck_data);
+
+ app_log("-----------------------\r\n");
+ app_log(" Discovery Start \r\n");
+ mikroe_pn7150_cmd_start_discovery();
+ sl_sleeptimer_delay_millisecond(100);
+
+ mikroe_pn7150_read_ctrl_packet_data(&ctrl_pck_data);
+ sl_sleeptimer_delay_millisecond(100);
+ display_packet(&ctrl_pck_data);
+
+ app_log("-----------------------\r\n");
+ app_log("-------- START --------\r\n");
+ app_log("-----------------------\r\n");
+ sl_sleeptimer_delay_millisecond(500);
+
+ app_log(" Application Task ");
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ while (mikroe_pn7150_check_irq() == NFC2_IRQ_STATE_HIGH) {
+ read_nfc_data(&ctrl_pck_data);
+ }
+
+ while (mikroe_pn7150_check_irq() == NFC2_IRQ_STATE_LOW) {}
+
+ app_log("-----------------------\r\n");
+ sl_sleeptimer_delay_millisecond(1000);
+}
+
+static void display_packet(mikroe_pn7150_control_packet_t *ctrl_pck)
+{
+ app_log("- - - - - - - - - - - -\r\n");
+ app_log(" Message Type = %d\r\n", ( uint16_t ) ctrl_pck->message_type);
+ app_log(" Pck Bound Flag = %d\r\n", ( uint16_t ) ctrl_pck->pck_bound_flag);
+ app_log(" Group Ident = %d\r\n", ( uint16_t ) ctrl_pck->group_ident);
+ app_log(" Opcode Ident = %d\r\n", ( uint16_t ) ctrl_pck->opcode_ident);
+ app_log(" Payload Length = %d\r\n", ( uint16_t ) ctrl_pck->payload_length);
+ app_log("- - - - - - - - - - - -\r\n");
+
+ for (uint8_t n_cnt = 0; n_cnt < ctrl_pck_data.payload_length; n_cnt++) {
+ app_log(" Payload[ %.2d ] = 0x%.2X\r\n", ( uint16_t ) n_cnt,
+ ( uint16_t ) ( uint16_t ) ctrl_pck_data.payload[n_cnt]);
+ }
+
+ app_log("- - - - - - - - - - - -\r\n");
+ memset(ctrl_pck_data.payload, 0x00, 255);
+}
+
+static void display_nfc_data(mikroe_pn7150_control_packet_t *ctrl_pck)
+{
+ app_log("- - - - - - - - - - - -\r\n");
+ app_log(" Read Block:\r\n");
+
+ for (uint8_t n_cnt = 1; n_cnt < ctrl_pck->payload_length - 2; n_cnt++) {
+ app_log("\t 0x%.2X \r\n", ( uint16_t ) ctrl_pck->payload[n_cnt]);
+ }
+ app_log("\t 0x%.2X \r\n",
+ ( uint16_t ) ctrl_pck->payload[ctrl_pck->payload_length - 2]);
+
+ app_log("- - - - - - - - - - - -\r\n");
+ memset(ctrl_pck->payload, 0x00, 255);
+}
+
+static void read_nfc_data(mikroe_pn7150_control_packet_t *ctrl_pck)
+{
+ mikroe_pn7150_read_ctrl_packet_data(ctrl_pck);
+ display_nfc_data(ctrl_pck);
+ app_log(" Disconnect Card \r\n");
+ mikroe_pn7150_cmd_card_disconnected();
+ sl_sleeptimer_delay_millisecond(10);
+ mikroe_pn7150_read_ctrl_packet_data(ctrl_pck);
+ sl_sleeptimer_delay_millisecond(10);
+
+ while (mikroe_pn7150_check_irq() == NFC2_IRQ_STATE_LOW) {}
+
+ mikroe_pn7150_read_ctrl_packet_data(ctrl_pck);
+ sl_sleeptimer_delay_millisecond(100);
+}
+
+static void test_antenna(mikroe_pn7150_control_packet_t *ctrl_pck)
+{
+ app_log("-----------------------\r\n");
+ app_log(" Testing Antenna ");
+ mikroe_pn7150_cmd_antenna_test(0x01);
+ sl_sleeptimer_delay_millisecond(100);
+
+ mikroe_pn7150_read_ctrl_packet_data(ctrl_pck);
+ sl_sleeptimer_delay_millisecond(100);
+
+ mikroe_pn7150_cmd_antenna_test(0x07);
+ sl_sleeptimer_delay_millisecond(100);
+ mikroe_pn7150_read_ctrl_packet_data(ctrl_pck);
+ sl_sleeptimer_delay_millisecond(100);
+
+ mikroe_pn7150_cmd_antenna_test(0x0F);
+ sl_sleeptimer_delay_millisecond(100);
+ mikroe_pn7150_read_ctrl_packet_data(ctrl_pck);
+ sl_sleeptimer_delay_millisecond(100);
+ display_packet(ctrl_pck);
+}
diff --git a/app/example/mikroe_nfc2_pn7150/app.h b/app/example/mikroe_nfc2_pn7150/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_nfc2_pn7150/main.c b/app/example/mikroe_nfc2_pn7150/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_nfc2_pn7150/mikroe_nfc2_pn7150.slcp b/app/example/mikroe_nfc2_pn7150/mikroe_nfc2_pn7150.slcp
new file mode 100644
index 00000000..4ad8d410
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150/mikroe_nfc2_pn7150.slcp
@@ -0,0 +1,50 @@
+project_name: mikroe_nfc2_pn7150
+label: Third Party Hardware Drivers - PN7150 - NFC 2 Click (Mikroe) - I2C
+description: |
+ This example project shows an example for PN7150 - NFC 2 Click board driver integration on I2C communication.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_nfc2_pn7150/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: device_init
+- id: i2cspm
+ instance: [mikroe]
+- id: sleeptimer
+- id: iostream_usart
+ instance: [vcom]
+- id: app_log
+- id: mikroe_nfc2
+ from: third_party_hw_drivers
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/mikroe_nfc2_pn7150/image/hardware_connection.png
+ directory: image
+ - path: ../../documentation/example/mikroe_nfc2_pn7150/image/create_example.png
+ directory: image
+ - path: ../../documentation/example/mikroe_nfc2_pn7150/image/log.png
+ directory: image
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_nfc2_pn7150_nci_t2t_read/app.c b/app/example/mikroe_nfc2_pn7150_nci_t2t_read/app.c
new file mode 100644
index 00000000..ec6af9e9
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150_nci_t2t_read/app.c
@@ -0,0 +1,324 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include
+#include "sl_i2cspm_instances.h"
+#include "sl_sleeptimer.h"
+#include "gpiointerrupt.h"
+#include "app_log.h"
+#include "app_assert.h"
+
+#include "t2t.h"
+#include "nci.h"
+#include "nfc_serial.h"
+
+#include "mikroe_pn7150_config.h"
+#include "mikroe_pn7150.h"
+
+static uint16_t read_index = 0;
+static uint16_t t2t_area_size = 0;
+
+static uint8_t data_buff[16];
+
+static void app_int_callback(uint8_t intNo);
+
+/*
+ * T2T Read Process
+ * -----------------------------------------------------------------------------
+ * ----- Preparation Sequence ------
+ * DH --> Core Reset CMD --> NFCC
+ * DH <-- Core Reset RSP <-- NFCC
+ * DH --> Core Init CMD --> NFCC
+ * DH <-- Core Init RSP <-- NFCC
+ * DH --> NXP Proprietary Act CMD --> NFCC
+ * DH <-- NXP Proprietary Act RSP <-- NFCC
+ * ----- RF Discover Phase ------
+ * DH --> RF Discover Map CMD --> NFCC
+ * (RF Prot. = PROTOCOL_T2T, Mode = Poll, RF Intf. = Frame RF)
+ * DH <-- RF Discover Map RSP <-- NFCC
+ * DH --> RF Discover CMD (NFC_A_PASSIVE_POLL_MODE) --> NFCC
+ * DH <-- RF Discover RSP <-- NFCC
+ * DH <-- RF Intf Activated NTF (Prot = PROTOCOL_T2T, Intf = Frame RF) <-- NFCC
+ * ----- Data Exhange Phase (REPEAT) ------
+ * DH --> NCI Data Message (READ Command, Block Address) <-- NFCC
+ * DH <-- Core Conn Credits NTF <-- NFCC
+ * DH <-- NCI Data Message (Read Response or NACK Response) <-- NFCC
+ * ----- RF Deactivate Phase ------
+ * DH --> RF Deactivate CMD (Discovery) <-- NFCC
+ * DH <-- RF Deactivate RSP <-- NFCC
+ * DH --> RF Deactivate NTF <-- NFCC
+ * ----- Go Back to RF Discover Phase ------
+ */
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+ // Initialize PN71x0 I2C communication.
+ if (SL_STATUS_OK != mikroe_pn7150_init(sl_i2cspm_mikroe)) {
+ app_log("> PN7150 - NFC 2 Click board driver init failed.\n");
+ }
+
+ GPIO_ExtIntConfig(MIKROE_PN7150_INT_PORT,
+ MIKROE_PN7150_INT_PIN,
+ MIKROE_PN7150_INT_PIN,
+ 1,
+ 0,
+ 1);
+ GPIOINT_CallbackRegister(MIKROE_PN7150_INT_PIN, app_int_callback);
+ GPIO_IntEnable(MIKROE_PN7150_INT_PIN);
+ app_log(" HW Reset \r\n");
+ mikroe_pn7150_hw_reset();
+
+ // Initialize NCI.
+ nci_init();
+
+ // Print project name.
+ app_log("\r\n******************************\r\n*\r\n");
+ app_log("* NCI T2T Read Demo\r\n");
+ app_log("*\r\n******************************\r\n");
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ // Get NCI event.
+ nci_evt_t *nci_evt = nci_get_event();
+
+ if (nci_evt->header == nci_evt_none) {
+ return;
+ }
+
+ // Log NCI event, if debug enabled.
+ nci_evt_log(nci_evt->header);
+
+ switch (nci_evt->header) {
+ /* Start up event, enter init sequence. */
+ case nci_evt_startup: {
+ /* Step 1 in init sequence: core reset. */
+ nci_core_reset_cmd_t core_reset_cmd;
+
+ /* Keep configurations. */
+ core_reset_cmd.reset_type = nci_core_reset_keep_config;
+
+ /* Send command and check for error/ */
+ nci_err_t nci_err = nci_core_reset(&core_reset_cmd);
+ app_assert(nci_err == nci_err_none,
+ "NCI core reset error: %x \r\n",
+ nci_err);
+ break;
+ }
+
+ /* Event generated by reception of core reset response. */
+ case nci_evt_core_reset_rsp_rec: {
+ /* Get core reset response data: NCI version of NFCC. */
+ uint8_t nci_version
+ = nci_evt->data.payload.nci_data.core_reset_rsp.nci_version;
+
+ /* Get core reset response data: configuration status. */
+ uint8_t config_status
+ = nci_evt->data.payload.nci_data.core_reset_rsp.config_status;
+
+ /* Log NCI version of NFCC. */
+ app_log("NFCC's NCI Version is %x.%x \r\n",
+ ((nci_version & 0xF0) >> 4),
+ (nci_version & 0x0F));
+
+ /* Log configuration status. */
+ if (config_status == nci_core_reset_keep_config) {
+ nci_log_ln("NCI RF Configuration has been kept.");
+ } else if (config_status == nci_core_reset_reset_conig) {
+ nci_log_ln("NCI RF Configuration has been reset. ");
+ }
+
+ /* Step 2 in init sequence: core init. */
+ /* Send command and check for error. */
+ nci_err_t nci_err = nci_core_init();
+ app_assert(nci_err == nci_err_none,
+ "NCI core init error: %x \r\n",
+ nci_err);
+ break;
+ }
+
+ /* Event generated by reception of core init response. */
+ case nci_evt_core_init_rsp_rec: {
+ uint8_t *manu_spec_info
+ = nci_evt->data.payload.nci_data.core_init_rsp.manu_spec_info;
+
+ app_log("NFCC's Firmware Version is %02x.%02x\r\n",
+ manu_spec_info[2],
+ manu_spec_info[3]);
+
+ /* Activate NXP proprietary extensions,
+ * send command and check for error.
+ */
+ nci_err_t nci_err = nci_proprietary_nxp_act();
+ app_assert(nci_err == nci_err_none,
+ "NCI core init error: %x \r\n",
+ nci_err);
+ break;
+ }
+
+ /* Event generated by reception of proprietary nxp act response. */
+ case nci_evt_proprietary_nxp_act_rsp_rec: {
+ nci_rf_mapping_config_t mapping_config_1 = {
+ .rf_protocol = nci_protocol_t2t,
+ .mode = nci_rf_mapping_mode_poll,
+ .rf_interface = nci_rf_interface_frame
+ };
+
+ nci_rf_mapping_config_t mapping_config[1] = { mapping_config_1 };
+
+ nci_rf_discover_map_cmd_t cmd = {
+ .num_of_mapping_config = 1,
+ .mapping_config = mapping_config
+ };
+
+ nci_err_t nci_err = nci_rf_discover_map(&cmd);
+ app_assert(nci_err == nci_err_none,
+ "NCI RF discovery map error: %x \r\n",
+ nci_err);
+ break;
+ }
+ case nci_evt_rf_discover_map_rsp_rec: {
+ if (nci_evt->data.payload.nci_data.rf_discover_map_rsp.status
+ != nci_status_ok) {
+ nci_log_ln("RF Discover Map Response status not ok.");
+ return;
+ }
+
+ uint8_t config[] = { nci_nfc_a_passive_poll_mode, 1 };
+
+ nci_rf_discover_cmd_t cmd = {
+ .num_of_config = 1,
+ .configurations = config
+ };
+
+ nci_err_t nci_err = nci_rf_discover(&cmd);
+ app_assert(nci_err == nci_err_none,
+ "NCI RF discovery error: %x \r\n",
+ nci_err);
+ break;
+ }
+
+ case nci_evt_rf_discover_rsp_rec: {
+ if (nci_evt->data.payload.nci_data.rf_discover_rsp.status
+ != nci_status_ok) {
+ nci_log_ln("RF Discover Response status not ok.");
+ return;
+ }
+
+ /* Wait for NTF */
+ break;
+ }
+ case nci_evt_rf_intf_activated_ntf_rec: {
+ uint8_t t2t_cmd_buff[] = { T2T_CMD_READ, read_index };
+
+ nci_data_packet_t pakcet = {
+ .pbf = nci_pbf_complete_msg,
+ .conn_id = 0,
+ .payload_len = 2,
+ .payload = t2t_cmd_buff
+ };
+
+ nci_err_t nci_err = nci_data_packet_send(&pakcet);
+ app_assert(nci_err == nci_err_none,
+ "NCI RF discovery map error: %x \r\n",
+ nci_err);
+ break;
+ }
+ case nci_evt_data_packet_rec: {
+ memcpy(data_buff,
+ nci_evt->data.payload.nci_data.rec_data_packet.payload,
+ 16);
+
+ if (read_index == 0) {
+ /* CC2, convert to size in blocks. */
+ t2t_area_size = data_buff[14] * 2;
+
+ /* Print header area. */
+ app_log("\r\nHeader: \r\nBlock 000 ");
+ serial_put_hex_and_ascii(&data_buff[0], 4);
+ app_log("\r\nBlock 001 ");
+ serial_put_hex_and_ascii(&data_buff[4], 4);
+ app_log("\r\nBlock 002 ");
+ serial_put_hex_and_ascii(&data_buff[8], 4);
+ app_log("\r\nBlock 003 ");
+ serial_put_hex_and_ascii(&data_buff[12], 4);
+ app_log("\r\n\r\nT2T Area (Size: %d blocks): \r\n", t2t_area_size);
+ } else if (((4 + t2t_area_size) - read_index) == 2) {
+ app_log("Block %03u to %03u ", read_index, (read_index + 1));
+ serial_put_hex(data_buff, 8);
+ app_log(" -- -- -- -- -- -- -- -- ");
+ serial_put_ascii(data_buff, 8);
+ app_log("\r\n");
+ } else {
+ app_log("Block %03u to %03u ", read_index, (read_index + 3));
+ serial_put_hex_and_ascii(data_buff, 16);
+ app_log("\r\n");
+ }
+
+ read_index += 4;
+
+ if (read_index < (t2t_area_size + 4)) {
+ uint8_t t2t_cmd_buff[] = { T2T_CMD_READ, read_index };
+
+ nci_data_packet_t pakcet = {
+ .pbf = nci_pbf_complete_msg,
+ .conn_id = 0,
+ .payload_len = 2,
+ .payload = t2t_cmd_buff
+ };
+ nci_err_t nci_err = nci_data_packet_send(&pakcet);
+ app_assert(nci_err == nci_err_none,
+ "NCI send packet error: %x \r\n",
+ nci_err);
+ } else {
+ read_index = 0;
+ nci_rf_deactivate_cmd_t cmd = {
+ .deactivate_type = nci_rf_deact_type_discovery_mode
+ };
+
+ nci_err_t nci_err = nci_rf_deactivate(&cmd);
+ app_assert(nci_err == nci_err_none,
+ "NCI rf deactive error: %x \r\n",
+ nci_err);
+ }
+
+ break;
+ }
+ case nci_evt_core_conn_credits_ntf_rec: {
+ break;
+ }
+ case nci_evt_rf_deactivate_rsp_rec: {
+ break;
+ }
+ case nci_evt_rf_deactivate_ntf_rec: {
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void app_int_callback(uint8_t intNo)
+{
+ (void) intNo;
+ nci_notify_incoming_packet();
+}
diff --git a/app/example/mikroe_nfc2_pn7150_nci_t2t_read/app.h b/app/example/mikroe_nfc2_pn7150_nci_t2t_read/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150_nci_t2t_read/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_nfc2_pn7150_nci_t2t_read/main.c b/app/example/mikroe_nfc2_pn7150_nci_t2t_read/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150_nci_t2t_read/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_nfc2_pn7150_nci_t2t_read/pn7150_nci_t2t_read.slcp b/app/example/mikroe_nfc2_pn7150_nci_t2t_read/pn7150_nci_t2t_read.slcp
new file mode 100644
index 00000000..f47a8de6
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150_nci_t2t_read/pn7150_nci_t2t_read.slcp
@@ -0,0 +1,63 @@
+project_name: pn7150_nci_t2t_read
+label: Third Party Hardware Drivers - PN7150 - Read a T2T Tag with NCI
+description: |
+ This example project demonstrates the interface of the NFC NCI service by using the NFC controller PN7150 to read a T2T Tag.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+
+readme:
+- path: ../../documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/README.md
+
+source:
+- path: app.c
+- path: main.c
+
+include:
+- path: ''
+ file_list:
+ - path: app.h
+
+component:
+- id: sl_system
+- id: device_init
+- id: gpiointerrupt
+- id: i2cspm
+ instance: [mikroe]
+- id: sleeptimer
+- id: iostream_usart
+ instance: [vcom]
+- id: app_log
+- id: app_assert
+- id: services_nfc_tag
+ from: third_party_hw_drivers
+- id: services_nfc_nci
+ from: third_party_hw_drivers
+- id: mikroe_nfc2
+ from: third_party_hw_drivers
+
+define:
+- name: DEBUG_EFM
+
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+
+other_file:
+ - path: ../../documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/hardware_connection.png
+ directory: image
+ - path: ../../documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/create_example.png
+ directory: image
+ - path: ../../documentation/example/mikroe_nfc2_pn7150_nci_t2t_read/image/log.png
+ directory: image
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_nfc2_pn7150_nci_t2t_write/app.c b/app/example/mikroe_nfc2_pn7150_nci_t2t_write/app.c
new file mode 100644
index 00000000..3658d82f
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150_nci_t2t_write/app.c
@@ -0,0 +1,396 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include
+#include "sl_i2cspm_instances.h"
+#include "sl_sleeptimer.h"
+#include "gpiointerrupt.h"
+#include "app_log.h"
+#include "app_assert.h"
+
+#include "t2t.h"
+#include "nci.h"
+#include "ndef_message.h"
+#include "nfc_tlv.h"
+
+#include "mikroe_pn7150_config.h"
+#include "mikroe_pn7150.h"
+
+static void app_int_callback(uint8_t intNo);
+
+/*
+ * T2T Write Process
+ * -----------------------------------------------------------------------------
+ * ----- Preparation Sequence ------
+ * DH --> Core Reset CMD --> NFCC
+ * DH <-- Core Reset RSP <-- NFCC
+ * DH --> Core Init CMD --> NFCC
+ * DH <-- Core Init RSP <-- NFCC
+ * DH --> NXP Proprietary Act CMD --> NFCC
+ * DH <-- NXP Proprietary Act RSP <-- NFCC
+ * ----- RF Discover Phase ------
+ * DH --> RF Discover Map CMD
+ * (RF Prot. = PROTOCOL_T2T, Mode = Poll, RF Intf. = Frame RF) --> NFCC
+ * DH <-- RF Discover Map RSP <-- NFCC
+ * DH --> RF Discover CMD (NFC_A_PASSIVE_POLL_MODE) --> NFCC
+ * DH <-- RF Discover RSP <-- NFCC
+ * DH <-- RF Intf Activated NTF (Prot = PROTOCOL_T2T, Intf = Frame RF) <-- NFCC
+ * ----- Data Exhange Phase (REPEAT) ------
+ * DH --> NCI Data Message (WRITE Command, Block Address, Data) <-- NFCC
+ * DH <-- Core Conn Credits NTF <-- NFCC
+ * DH <-- NCI Data Message (ACK or NACK Response) <-- NFCC
+ * ----- RF Deactivate Phase ------
+ * DH --> RF Deactivate CMD (Discovery) <-- NFCC
+ * DH <-- RF Deactivate RSP <-- NFCC
+ * DH --> RF Deactivate NTF <-- NFCC
+ * ----- Go Back to RF Discover Phase ------
+ */
+
+#define TLV_BUFFER_SIZE 100
+#define PAYLOAD_BUFFER_SIZE 100
+
+char *content = "silabs.com/wireless/bluetooth";
+uint8_t payload[PAYLOAD_BUFFER_SIZE];
+
+ndef_record_t record = {
+ .header = {
+ .mb = 1,
+ .me = 1,
+ .cf = 0,
+ .sr = 1,
+ .il = 0,
+ .tnf = ndefTnfWellKnown
+ },
+ .type_length = 1,
+ .type = (uint8_t *) NDEF_RTD_WKT_GLOBAL_URI
+};
+
+ndef_record_t ndef_message[1];
+
+uint8_t ndef_message_buff[TLV_BUFFER_SIZE - 3];
+uint8_t tlv_buff[TLV_BUFFER_SIZE];
+
+// uint8_t conn_credits = 0;
+uint16_t write_index = 0;
+uint32_t write_size;
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+ // Initialize PN71x0 I2C communication.
+ if (SL_STATUS_OK != mikroe_pn7150_init(sl_i2cspm_mikroe)) {
+ app_log("> PN7150 - NFC 2 Click board driver init failed.\n");
+ }
+
+ GPIO_ExtIntConfig(MIKROE_PN7150_INT_PORT,
+ MIKROE_PN7150_INT_PIN,
+ MIKROE_PN7150_INT_PIN,
+ 1,
+ 0,
+ 1);
+ GPIOINT_CallbackRegister(MIKROE_PN7150_INT_PIN, app_int_callback);
+ GPIO_IntEnable(MIKROE_PN7150_INT_PIN);
+ app_log(" HW Reset \r\n");
+ mikroe_pn7150_hw_reset();
+
+ // Initialize NCI.
+ nci_init();
+
+ /* Print project name. */
+ app_log("\r\n******************************\r\n*\r\n");
+ app_log("* NCI T2T Write Demo\r\n");
+ app_log("*\r\n******************************\r\n");
+
+ app_log("Write content: %s\r\n", content);
+
+ record.payload = payload;
+ // prefix + content
+ record.payload_length = 1 + strlen(content);
+
+ ndef_message[0] = record;
+
+ payload[0] = NDEF_RTD_WKT_URI_PREFIX_HTTPS;
+
+ memcpy(&payload[1], content, strlen(content));
+
+ // encode ndef message
+ ndef_message_encode_result_t ndef_message_encode_result;
+ ndef_message_encode_result = ndef_message_encode(ndef_message_buff,
+ ndef_message);
+ if (ndef_message_encode_result.err == ndefMessageEncodeFail) {
+ app_log("NDEF message encode failed:(\r\n");
+ return;
+ }
+
+ write_size = ndef_message_encode_result.size;
+
+ // encode ndef tlv
+ if (tlv_encode(tlv_buff,
+ TLV_BUFFER_SIZE,
+ NFC_T2T_NDEF_MESSAGE_TLV, // T
+ ndef_message_encode_result.size, // L
+ ndef_message_buff // V
+ ) != tlvEncodeCompleted) {
+ app_log("NDEF TLV encode failed:(\r\n");
+ return;
+ }
+
+ write_size += 2;
+
+ if (tlv_encode(&tlv_buff[write_size],
+ (TLV_BUFFER_SIZE - write_size),
+ NFC_T2T_TERMINATOR_TLV, // T
+ 0, // L
+ NULL // V
+ ) != tlvEncodeCompleted) {
+ app_log("Terminator TLV encode failed:(\r\n");
+ return;
+ }
+
+ write_size++;
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ /* Get NCI event. */
+ nci_evt_t *nci_evt = nci_get_event();
+
+ if (nci_evt->header == nci_evt_none) {
+ return;
+ }
+
+ /* Log NCI event, if debug enabled. */
+ nci_evt_log(nci_evt->header);
+
+ switch (nci_evt->header) {
+ /* Start up event, enter init sequence. */
+ case nci_evt_startup: {
+ /* Step 1 in init sequence: core reset. */
+ nci_core_reset_cmd_t core_reset_cmd;
+
+ /* Keep configurations. */
+ core_reset_cmd.reset_type = nci_core_reset_keep_config;
+
+ /* Send command and check for error/ */
+ nci_err_t nci_err = nci_core_reset(&core_reset_cmd);
+ app_assert(nci_err == nci_err_none,
+ "NCI core reset error: %x \r\n",
+ nci_err);
+ break;
+ }
+
+ /* Event generated by reception of core reset response. */
+ case nci_evt_core_reset_rsp_rec: {
+ /* Get core reset response data: NCI version of NFCC. */
+ uint8_t nci_version =
+ nci_evt->data.payload.nci_data.core_reset_rsp.nci_version;
+
+ /* Get core reset response data: configuration status. */
+ uint8_t config_status =
+ nci_evt->data.payload.nci_data.core_reset_rsp.config_status;
+
+ /* Log NCI version of NFCC. */
+ app_log("NFCC's NCI Version is %x.%x\r\n",
+ ((nci_version & 0xF0) >> 4),
+ (nci_version & 0x0F));
+
+ /* Log configuration status. */
+ if (config_status == nci_core_reset_keep_config) {
+ nci_log_ln("NCI RF Configuration has been kept.");
+ } else if (config_status == nci_core_reset_reset_conig) {
+ nci_log_ln("NCI RF Configuration has been reset. ");
+ }
+
+ /* Step 2 in init sequence: core init.
+ * Send command and check for error.
+ */
+ nci_err_t nci_err = nci_core_init();
+ app_assert(nci_err == nci_err_none,
+ "NCI core init error: %x \r\n",
+ nci_err);
+ break;
+ }
+
+ /* Event generated by reception of core init response. */
+ case nci_evt_core_init_rsp_rec: {
+ uint8_t *manu_spec_info =
+ nci_evt->data.payload.nci_data.core_init_rsp.manu_spec_info;
+
+ app_log("NFCC's Firmware Version is %02x.%02x\r\n",
+ manu_spec_info[2],
+ manu_spec_info[3]);
+
+ /* Activate NXP proprietary extensions,
+ * send command and check for error.
+ */
+ nci_err_t nci_err = nci_proprietary_nxp_act();
+ app_assert(nci_err == nci_err_none,
+ "NCI core init error: %x \r\n",
+ nci_err);
+ break;
+ }
+
+ /* Event generated by reception of proprietary nxp act response. */
+ case nci_evt_proprietary_nxp_act_rsp_rec: {
+ nci_rf_mapping_config_t mapping_config_1 = {
+ .rf_protocol = nci_protocol_t2t,
+ .mode = nci_rf_mapping_mode_poll,
+ .rf_interface = nci_rf_interface_frame
+ };
+
+ nci_rf_mapping_config_t mapping_config[1] = { mapping_config_1 };
+
+ nci_rf_discover_map_cmd_t cmd = {
+ .num_of_mapping_config = 1,
+ .mapping_config = mapping_config
+ };
+
+ nci_err_t nci_err = nci_rf_discover_map(&cmd);
+ app_assert(nci_err == nci_err_none,
+ "NCI RF discovery map error: %x \r\n",
+ nci_err);
+ break;
+ }
+
+ case nci_evt_rf_discover_map_rsp_rec: {
+ if (nci_evt->data.payload.nci_data.rf_discover_map_rsp.status
+ != nci_status_ok) {
+ nci_log_ln("RF Discover Map Response status not ok.");
+ return;
+ }
+
+ uint8_t config[] = { nci_nfc_a_passive_poll_mode, 1 };
+
+ nci_rf_discover_cmd_t cmd = {
+ .num_of_config = 1,
+ .configurations = config
+ };
+
+ nci_err_t nci_err = nci_rf_discover(&cmd);
+ app_assert(nci_err == nci_err_none,
+ "NCI RF discovery error: %x \r\n",
+ nci_err);
+ break;
+ }
+
+ case nci_evt_rf_discover_rsp_rec: {
+ if (nci_evt->data.payload.nci_data.rf_discover_rsp.status
+ != nci_status_ok) {
+ nci_log_ln("RF Discover Response status not ok.");
+ return;
+ }
+
+ /* Wait for NTF */
+ break;
+ }
+
+ case nci_evt_rf_intf_activated_ntf_rec: {
+ uint8_t t2t_cmd_buff[] = {
+ T2T_CMD_WRITE,
+ write_index + 4,
+ tlv_buff[write_index * 4],
+ tlv_buff[write_index * 4 + 1],
+ tlv_buff[write_index * 4 + 2],
+ tlv_buff[write_index * 4 + 3]
+ };
+
+ nci_data_packet_t pakcet = {
+ .pbf = nci_pbf_complete_msg,
+ .conn_id = 0,
+ .payload_len = 6,
+ .payload = t2t_cmd_buff
+ };
+
+ nci_err_t nci_err = nci_data_packet_send(&pakcet);
+ app_assert(nci_err == nci_err_none,
+ "NCI RF discovery map error: %x \r\n",
+ nci_err);
+ break;
+ }
+ case nci_evt_data_packet_rec: {
+ if (nci_evt->data.payload.nci_data.rec_data_packet.payload[0]
+ != T2T_RSP_ACK) {
+ app_log("T2T Write NACK response. \r\n");
+ }
+
+ write_index++;
+
+ int num_bytes_to_write = write_size - (write_index * 4);
+
+ uint8_t t2t_cmd_buff[6] = { 0 };
+
+ if (num_bytes_to_write > 0) {
+ t2t_cmd_buff[0] = T2T_CMD_WRITE;
+ t2t_cmd_buff[1] = write_index + 4;
+ t2t_cmd_buff[2] = tlv_buff[write_index * 4];
+ if (num_bytes_to_write >= 4) {
+ t2t_cmd_buff[3] = tlv_buff[write_index * 4 + 1];
+ t2t_cmd_buff[4] = tlv_buff[write_index * 4 + 2];
+ t2t_cmd_buff[5] = tlv_buff[write_index * 4 + 3];
+ } else if (num_bytes_to_write == 3) {
+ t2t_cmd_buff[3] = tlv_buff[write_index * 4 + 1];
+ t2t_cmd_buff[4] = tlv_buff[write_index * 4 + 2];
+ } else if (num_bytes_to_write == 2) {
+ t2t_cmd_buff[3] = tlv_buff[write_index * 4 + 1];
+ }
+ nci_data_packet_t pakcet = {
+ .pbf = nci_pbf_complete_msg,
+ .conn_id = 0,
+ .payload_len = 6,
+ .payload = t2t_cmd_buff
+ };
+ nci_data_packet_send(&pakcet);
+ } else {
+ app_log("T2T write completed.\r\n");
+ write_index = 0;
+ nci_rf_deactivate_cmd_t cmd = {
+ .deactivate_type = nci_rf_deact_type_discovery_mode
+ };
+
+ nci_err_t nci_err = nci_rf_deactivate(&cmd);
+ app_assert(nci_err == nci_err_none,
+ "NCI rf deactive error: %x \r\n",
+ nci_err);
+ }
+
+ break;
+ }
+ case nci_evt_core_conn_credits_ntf_rec: {
+ break;
+ }
+ case nci_evt_rf_deactivate_rsp_rec: {
+ break;
+ }
+ case nci_evt_rf_deactivate_ntf_rec: {
+ break;
+ }
+
+ /* Meh */
+ default:
+ break;
+ }
+}
+
+static void app_int_callback(uint8_t intNo)
+{
+ (void) intNo;
+ nci_notify_incoming_packet();
+}
diff --git a/app/example/mikroe_nfc2_pn7150_nci_t2t_write/app.h b/app/example/mikroe_nfc2_pn7150_nci_t2t_write/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150_nci_t2t_write/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_nfc2_pn7150_nci_t2t_write/main.c b/app/example/mikroe_nfc2_pn7150_nci_t2t_write/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150_nci_t2t_write/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_nfc2_pn7150_nci_t2t_write/pn7150_nci_t2t_write.slcp b/app/example/mikroe_nfc2_pn7150_nci_t2t_write/pn7150_nci_t2t_write.slcp
new file mode 100644
index 00000000..6ad0320e
--- /dev/null
+++ b/app/example/mikroe_nfc2_pn7150_nci_t2t_write/pn7150_nci_t2t_write.slcp
@@ -0,0 +1,65 @@
+project_name: pn7150_nci_t2t_write
+label: Third Party Hardware Drivers - PN7150 - Write to a T2T Tag with NCI
+description: |
+ This example project demonstrates the interface of the NFC NCI service by the NFC controller PN7150 to write to a T2T Tag.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+
+readme:
+- path: ../../documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/README.md
+
+source:
+- path: app.c
+- path: main.c
+
+include:
+- path: ''
+ file_list:
+ - path: app.h
+
+component:
+- id: sl_system
+- id: device_init
+- id: gpiointerrupt
+- id: i2cspm
+ instance: [mikroe]
+- id: sleeptimer
+- id: iostream_usart
+ instance: [vcom]
+- id: app_log
+- id: app_assert
+- id: services_nfc_tag
+ from: third_party_hw_drivers
+- id: services_nfc_nci
+ from: third_party_hw_drivers
+- id: services_nfc_ndef
+ from: third_party_hw_drivers
+- id: mikroe_nfc2
+ from: third_party_hw_drivers
+
+define:
+- name: DEBUG_EFM
+
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+
+other_file:
+ - path: ../../documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/hardware_connection.png
+ directory: image
+ - path: ../../documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/create_example.png
+ directory: image
+ - path: ../../documentation/example/mikroe_nfc2_pn7150_nci_t2t_write/image/log.png
+ directory: image
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_nfctag2_nt3h2111/app.c b/app/example/mikroe_nfctag2_nt3h2111/app.c
new file mode 100644
index 00000000..3c58230f
--- /dev/null
+++ b/app/example/mikroe_nfctag2_nt3h2111/app.c
@@ -0,0 +1,291 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include
+#include "sl_i2cspm_instances.h"
+#include "app_log.h"
+#include "sl_sleeptimer.h"
+#include "mikroe_nt3h2111.h"
+#include "sl_iostream.h"
+
+sl_iostream_t *default_iostream;
+
+// #define NTAG_I2C_BLOCK_SIZE 16
+
+static uint16_t wdt_timer = 0;
+
+static const uint8_t default_begining_of_memory[] = {
+ 0xAA, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0xE1, 0x10, 0x6D, 0x00
+};
+
+static const uint8_t ndef_rec[] = {
+ 0x03, // NDEF Message
+ 15, // Message size
+ 0xD1, // Record header
+ 1, // Type Length - 1 byte
+ 11, // Payload Length - 11 bytes
+ 'U', // Type / URI
+ 0x01, // Payload
+ 's', 'i', 'l', 'a', 'b', 's', '.', 'c', 'o', 'm',
+ 0xFE // NDEF Message End Mark
+};
+
+static const uint8_t null_block[] = {
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t default_page_56[] = {
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xFF
+};
+
+static const uint8_t default_page_57[] = {
+ 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+static const uint8_t default_page_58[] = {
+ 0x01, 0x00, 0xF8, 0x48,
+ 0x08, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+static sl_status_t factory_reset_tag(void);
+static sl_status_t test_read_session(void);
+static sl_status_t test_write_session(void);
+static uint8_t read_input (void);
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+ /* Initialize NT3H2111 I2C communication. */
+ nt3h2111_init(sl_i2cspm_mikroe);
+
+ default_iostream = sl_iostream_get_default();
+
+ /* Print project name. */
+ app_log(
+ "\r\n*********************************************************\r\n*\r\n");
+ app_log("* Third Party Hardware Drivers - NT3H2111 - NFC Tag 2 Click\r\n");
+ app_log("*\r\n*********************************************************\r\n");
+ app_log("*\r\n* Give a input, your input should be between 0 and 4.\r\n");
+ app_log("* Press enter when you finish.\r\n");
+ app_log("*\r\n* 0. Factory reset Tag\r\n");
+ app_log("*\r\n* 1. Read the session registers\r\n");
+ app_log("*\r\n* 2. Write the session registers\r\n");
+ app_log("*\r\n* 3. Write Tag\r\n");
+ app_log("*\r\n* 4. Read Tag\r\n");
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ sl_status_t stt;
+ uint8_t input_cmd = 0;
+
+ app_log("\r\nGive a your number, press enter when you finish: ");
+ app_log("\r\n>");
+ input_cmd = read_input();
+ switch (input_cmd) {
+ case 0:
+ app_log("Start to reset the memory to its default values\r\n");
+ stt = factory_reset_tag();
+ if (stt == SL_STATUS_OK) {
+ app_log("Reset successful!\r\n");
+ } else {
+ app_log("Reseting Failed with Err = 0x%lx\r\n", stt);
+ }
+ break;
+ case 1:
+ app_log("Start reading the content of Session Watchdog Timer\r\n");
+ stt = test_read_session();
+ if (stt == SL_STATUS_OK) {
+ app_log("Current Watchdog Timer = %d\r\n", wdt_timer);
+ } else {
+ app_log("Read Watchdog Timer Failed with Err = 0x%lx\r\n", stt);
+ }
+ break;
+ case 2:
+ app_log("Start writing new value to the Session Watchdog Timer\r\n");
+ stt = test_write_session();
+ if (stt == SL_STATUS_OK) {
+ app_log("Wrote successful Watchdog Timer to new value = %d\r\n",
+ wdt_timer);
+ } else {
+ app_log("Set Watchdog Timer Failed with Err = 0x%lx\r\n", stt);
+ }
+ break;
+ case 3:
+ // Write an NDEF message into NT3H2111 EEPROM.
+ app_log("Start writing an NDEF message into NT3H2111 EEPROM\r\n");
+ stt = nt3h2111_write_bytes(16, ndef_rec, sizeof(ndef_rec));
+ if (stt == SL_STATUS_OK) {
+ app_log("Write Tag successful\r\n");
+ } else {
+ app_log("Writing Tag failed with Err = 0x%lx\r\n", stt);
+ }
+ break;
+ case 4:
+ {
+ uint8_t buff[32];
+ app_log("Start reading from NT3H2111 EEPROM\r\n");
+ stt = nt3h2111_read_bytes(16, buff, 32);
+ if (stt == SL_STATUS_OK) {
+ app_log("Read Tag successful!\r\n");
+ for (int i = 0; i < 8; i++) {
+ app_log(" 0x%02x, 0x%02x, 0x%02x, 0x%02x\r\n",
+ buff[4 * i],
+ buff[4 * i + 1],
+ buff[4 * i + 2],
+ buff[4 * i + 3]);
+ }
+ } else {
+ app_log("Read failed with Err = 0x%lx\r\n", stt);
+ }
+ }
+ break;
+ }
+ app_log("*\r\n*********************************************************\r\n");
+}
+
+/*
+ * Example how to use :
+ * - nt3h2111_write_bytes
+ * - nt3h2111_write_block
+ *
+ * Resets the memory to its default values
+ */
+static sl_status_t factory_reset_tag(void)
+{
+ sl_status_t result;
+
+ // Reset default eeprom memory values (smart poster)
+ result = nt3h2111_write_block(0, default_begining_of_memory);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+
+ // Reset pages from 1 to 56
+ uint8_t page = 1;
+ while (page < 56) {
+ result = nt3h2111_write_block(page, null_block);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+ page++;
+ }
+ // Reset pages 56,57,58
+ result = nt3h2111_write_block(56, default_page_56);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+ result = nt3h2111_write_block(57, default_page_57);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+ result = nt3h2111_write_block(58, default_page_58);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+
+ return SL_STATUS_OK;
+}
+
+/*
+ * Example how to use :
+ * - nfctag2_session_get
+ * - nfctag2_session_set
+ *
+ * Dumps the content of Session Watchdog Timer
+ * Changing of session settings
+ */
+static sl_status_t test_read_session(void)
+{
+ sl_status_t stt;
+ uint8_t temp[2];
+
+ stt = nt3h2111_get_session(SESSION_WDT_LS, &temp[0]);
+ stt |= nt3h2111_get_session(SESSION_WDT_MS, &temp[1]);
+ if (stt == SL_STATUS_OK) {
+ wdt_timer = (uint16_t)temp[1] << 8 | temp[0];
+ }
+ return stt;
+}
+
+static sl_status_t test_write_session(void)
+{
+ sl_status_t stt;
+
+ wdt_timer++;
+ stt = nt3h2111_set_session(SESSION_WDT_MS, 0xff, wdt_timer >> 8);
+ stt |= nt3h2111_set_session(SESSION_WDT_LS, 0xff, wdt_timer & 0xff);
+ return stt;
+}
+
+static uint8_t read_input(void)
+{
+ char char_buff;
+ size_t bytes_read;
+ uint8_t input_cmd = 0;
+ uint8_t size_len = 0;
+
+ while (1) {
+ sl_iostream_read(default_iostream, &char_buff, 1, &bytes_read);
+
+ if (bytes_read > 0) {
+ if ((char_buff >= '0') && (char_buff <= '4')) {
+ if (size_len < 1) {
+ input_cmd = char_buff - '0';
+ size_len++;
+ app_log("%c", char_buff);
+ } else {
+ app_log(
+ "\r\ntoo many digits. Please input a number between 0 and 4, press ENTER when you finish:");
+ size_len = 0;
+ }
+ } else if (char_buff == '\r') {
+ if (size_len == 0) {
+ app_log(
+ "\r\nPlease input a number between 0 and 9, press ENTER when you finish: ");
+ continue;
+ }
+ app_log("\r\n");
+ break;
+ } else {
+ app_log(
+ "\r\nInvalid character. Please input a number between 0 and 4, press ENTER when you finish: ");
+ size_len = 0;
+ }
+ }
+ }
+
+ return input_cmd;
+}
diff --git a/app/example/mikroe_nfctag2_nt3h2111/app.h b/app/example/mikroe_nfctag2_nt3h2111/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_nfctag2_nt3h2111/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_nfctag2_nt3h2111/main.c b/app/example/mikroe_nfctag2_nt3h2111/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_nfctag2_nt3h2111/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_nfctag2_nt3h2111/mikroe_nfctag2_nt3h2111.slcp b/app/example/mikroe_nfctag2_nt3h2111/mikroe_nfctag2_nt3h2111.slcp
new file mode 100644
index 00000000..05854aae
--- /dev/null
+++ b/app/example/mikroe_nfctag2_nt3h2111/mikroe_nfctag2_nt3h2111.slcp
@@ -0,0 +1,51 @@
+project_name: mikroe_nfctag2_nt3h2111
+label: Third Party Hardware Drivers - NT3H2111 - NFC Tag 2 Click (Mikroe) - I2C
+description: |
+ This example project shows an example for NT3H2111 - NFC Tag 2 Click board driver integration on I2C communication.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_nfctag2_nt3h2111/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: device_init
+- id: i2cspm
+ instance: [mikroe]
+- id: iostream_usart
+ instance: [vcom]
+- id: app_log
+- id: mikroe_nfctag2
+ from: third_party_hw_drivers
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/mikroe_nfctag2_nt3h2111/image/hardware_connection.png
+ directory: image
+ - path: ../../documentation/example/mikroe_nfctag2_nt3h2111/image/create_example.png
+ directory: image
+ - path: ../../documentation/example/mikroe_nfctag2_nt3h2111/image/log.png
+ directory: image
+ - path: ../../documentation/example/mikroe_nfctag2_nt3h2111/image/nfc_tools.png
+ directory: image
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_oledc_ssd1351/app.c b/app/example/mikroe_oledc_ssd1351/app.c
new file mode 100644
index 00000000..c4ebc404
--- /dev/null
+++ b/app/example/mikroe_oledc_ssd1351/app.c
@@ -0,0 +1,133 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_spidrv_instances.h"
+#include "sl_simple_timer.h"
+
+#include "oledc_font.h"
+#include "mikroe_ssd1351_image.h"
+#include "mikroe_ssd1351.h"
+#include "glib.h"
+
+#include "app_log.h"
+#include "app_assert.h"
+
+#define APP_STATE_DISPLAY_RECTANGLE 0
+#define APP_STATE_DISPLAY_LINE 1
+#define APP_STATE_DISPLAY_IMAGE 2
+
+static sl_simple_timer_t display_timer_handle;
+static glib_context_t glib_context;
+static volatile uint8_t state = APP_STATE_DISPLAY_RECTANGLE;
+
+// Timer callback function
+static void display_timer_callback(sl_simple_timer_t *handle,
+ void *data);
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+ sl_status_t sc;
+
+ app_log("---- Application Init ----\r\n");
+ // Click initialization.
+ sc = mikroe_ssd1351_init(sl_spidrv_mikroe_handle);
+ app_assert_status(sc);
+ glib_init(&glib_context);
+ glib_set_bg_color(&glib_context, 0xFFFF);
+ glib_set_text_color(&glib_context, 0x0000);
+ glib_enable_display(true);
+
+ // demo with API of GLIB
+ glib_clear(&glib_context);
+ glib_fill(&glib_context, 0xFF00);
+ glib_update_display();
+
+ glib_fill(&glib_context, 0xFFFF);
+ glib_update_display();
+
+ glib_draw_string(&glib_context, "SILICON LABS", 15, 25);
+ glib_draw_string(&glib_context, "DEMO", 35, 45);
+ glib_draw_string(&glib_context, "OLED C CLICK", 10, 65);
+ glib_update_display();
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ switch (state)
+ {
+ case APP_STATE_DISPLAY_RECTANGLE:
+ mikroe_ssd1351_rectangle(0, 0, 96, 96, 0xF000);
+ mikroe_ssd1351_rectangle(5, 5, 91, 91, 0xFF00);
+ mikroe_ssd1351_rectangle(10, 10, 86, 86, 0x00F0);
+ mikroe_ssd1351_rectangle(15, 15, 81, 81, 0x0F0F);
+ mikroe_ssd1351_rectangle(20, 20, 76, 76, 0xF000);
+ mikroe_ssd1351_rectangle(25, 25, 71, 71, 0xFF00);
+ break;
+
+ case APP_STATE_DISPLAY_LINE:
+ mikroe_ssd1351_rectangle(25, 25, 71, 27, 0);
+ mikroe_ssd1351_rectangle(25, 71, 71, 73, 0);
+ mikroe_ssd1351_rectangle(25, 25, 27, 71, 0);
+ mikroe_ssd1351_rectangle(68, 25, 71, 71, 0);
+ break;
+
+ case APP_STATE_DISPLAY_IMAGE:
+ mikroe_ssd1351_fill_screen(0xFFFF);
+ mikroe_ssd1351_image(aclogo, 0, 0);
+ mikroe_ssd1351_image(mikroe_with_slogan, 0, 62);
+ break;
+
+ default:
+ break;
+ }
+ sl_simple_timer_start(&display_timer_handle,
+ 500,
+ display_timer_callback,
+ NULL,
+ 0);
+}
+
+// Timer callback function
+static void display_timer_callback(sl_simple_timer_t *handle,
+ void *data)
+{
+ (void) handle;
+ (void) data;
+
+ switch (state)
+ {
+ case APP_STATE_DISPLAY_RECTANGLE:
+ state = APP_STATE_DISPLAY_LINE;
+ break;
+
+ case APP_STATE_DISPLAY_LINE:
+ state = APP_STATE_DISPLAY_IMAGE;
+ break;
+
+ case APP_STATE_DISPLAY_IMAGE:
+ state = APP_STATE_DISPLAY_RECTANGLE;
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/app/example/mikroe_oledc_ssd1351/app.h b/app/example/mikroe_oledc_ssd1351/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_oledc_ssd1351/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_oledc_ssd1351/main.c b/app/example/mikroe_oledc_ssd1351/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_oledc_ssd1351/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_oledc_ssd1351/mikroe_oledc_ssd1351.slcp b/app/example/mikroe_oledc_ssd1351/mikroe_oledc_ssd1351.slcp
new file mode 100644
index 00000000..aa2d166d
--- /dev/null
+++ b/app/example/mikroe_oledc_ssd1351/mikroe_oledc_ssd1351.slcp
@@ -0,0 +1,52 @@
+# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file.
+project_name: mikroe_oledc_ssd1351
+label: Third Party Hardware Drivers - SSD1351 - OLED C Click Board (Mikroe)
+description: |
+ This example project shows an example for Mikroe OLEDC Click driver integration.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_oledc_ssd1351/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: device_init
+- id: iostream_usart
+ instance: [vcom]
+- id: oledc_ssd1351
+ from: third_party_hw_drivers
+- id: services_oled_glib
+ from: third_party_hw_drivers
+- id: app_log
+- id: app_assert
+- id: simple_timer
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/mikroe_oledc_ssd1351/image/hardware_connection.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_oledc_ssd1351/image/create_example.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_oledc_ssd1351/image/test.gif
+ directory: "image"
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_oledw_ssd1306/mikroe_oledw_ssd1306.slcp b/app/example/mikroe_oledw_ssd1306/mikroe_oledw_ssd1306.slcp
index d6dff584..4ccf800b 100644
--- a/app/example/mikroe_oledw_ssd1306/mikroe_oledw_ssd1306.slcp
+++ b/app/example/mikroe_oledw_ssd1306/mikroe_oledw_ssd1306.slcp
@@ -39,7 +39,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_oledw_ssd1306/hardware_connection.png
- path: ../../documentation/example/mikroe_oledw_ssd1306/create_example.png
diff --git a/app/example/mikroe_oledw_ssd1306_glib/mikroe_oledw_ssd1306_glib.slcp b/app/example/mikroe_oledw_ssd1306_glib/mikroe_oledw_ssd1306_glib.slcp
index 6a0eeaf9..a5927c0e 100644
--- a/app/example/mikroe_oledw_ssd1306_glib/mikroe_oledw_ssd1306_glib.slcp
+++ b/app/example/mikroe_oledw_ssd1306_glib/mikroe_oledw_ssd1306_glib.slcp
@@ -44,7 +44,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_oledw_ssd1306_glib/hardware_connection.png
- path: ../../documentation/example/mikroe_oledw_ssd1306_glib/create_example.png
diff --git a/app/example/mikroe_pressure3_dps310/app.c b/app/example/mikroe_pressure3_dps310/app.c
new file mode 100644
index 00000000..b820733a
--- /dev/null
+++ b/app/example/mikroe_pressure3_dps310/app.c
@@ -0,0 +1,87 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_status.h"
+#include "sl_sleeptimer.h"
+#include "app_log.h"
+
+#ifdef SL_CATALOG_MIKROE_PRESSURE3_SPI_PRESENT
+#include "sl_spidrv_instances.h"
+#include "mikroe_dps310_spi.h"
+#endif
+
+#ifdef SL_CATALOG_MIKROE_PRESSURE3_I2C_PRESENT
+#include "sl_i2cspm_instances.h"
+#include "mikroe_dps310_i2c.h"
+#endif
+
+#define READING_INTERVAL_MSEC 500
+
+static volatile bool enable_reading_data = false;
+static sl_sleeptimer_timer_handle_t app_periodic_timer;
+
+static void app_periodic_timer_cb(sl_sleeptimer_timer_handle_t *timer,
+ void *data);
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+#ifdef SL_CATALOG_MIKROE_PRESSURE3_SPI_PRESENT
+ mikroe_pressure3_init(sl_spidrv_mikroe_handle);
+#endif
+
+#ifdef SL_CATALOG_MIKROE_PRESSURE3_I2C_PRESENT
+ mikroe_pressure3_init(sl_i2cspm_mikroe);
+#endif
+
+ app_log("Sensor initialization done.\n");
+ // Start periodic timer used for read data from sensor.
+ sl_sleeptimer_start_periodic_timer(&app_periodic_timer,
+ READING_INTERVAL_MSEC,
+ app_periodic_timer_cb,
+ (void *) NULL,
+ 0,
+ 0);
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ float pressure;
+ float temperature;
+
+ if (enable_reading_data) {
+ enable_reading_data = false;
+
+ mikroe_pressure3_get_t_p_data(&temperature, &pressure);
+ app_log(" * Pressure: %.2f mbar * \r\n", pressure);
+ app_log(" * Temperature: %.2f C * \r\n", temperature);
+ app_log(" ----------------------- \r\n");
+ }
+}
+
+static void app_periodic_timer_cb(sl_sleeptimer_timer_handle_t *timer,
+ void *data)
+{
+ (void)timer;
+ (void)data;
+
+ enable_reading_data = true;
+}
diff --git a/app/example/mikroe_pressure3_dps310/app.h b/app/example/mikroe_pressure3_dps310/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_pressure3_dps310/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_pressure3_dps310/main.c b/app/example/mikroe_pressure3_dps310/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_pressure3_dps310/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_pressure3_dps310/mikroe_pressure3_dps310_i2c.slcp b/app/example/mikroe_pressure3_dps310/mikroe_pressure3_dps310_i2c.slcp
new file mode 100644
index 00000000..e4b3d46d
--- /dev/null
+++ b/app/example/mikroe_pressure3_dps310/mikroe_pressure3_dps310_i2c.slcp
@@ -0,0 +1,58 @@
+# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file.
+project_name: mikroe_pressure3_dps310_i2c
+label: Third Party Hardware Drivers - DPS310 - Pressure 3 click (Mikroe) - I2C
+description: |
+ This example project shows an example for DPS310 - Pressure 3 click board driver integration on I2C communication.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_pressure3_dps310/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: device_init
+- id: i2cspm
+ instance: [mikroe]
+- id: spidrv
+ instance: [mikroe]
+- id: iostream_usart
+ instance: [vcom]
+- id: app_log
+- id: sleeptimer
+- id: mikroe_pressure3_i2c
+ from: third_party_hw_drivers
+toolchain_settings:
+ - option: gcc_linker_option
+ value: "-u _printf_float"
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/mikroe_pressure3_dps310/image/create_example.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pressure3_dps310/image/hardware_connection.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pressure3_dps310/image/log.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pressure3_dps310/image/float.png
+ directory: "image"
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_pressure3_dps310/mikroe_pressure3_dps310_spi.slcp b/app/example/mikroe_pressure3_dps310/mikroe_pressure3_dps310_spi.slcp
new file mode 100644
index 00000000..36e421a4
--- /dev/null
+++ b/app/example/mikroe_pressure3_dps310/mikroe_pressure3_dps310_spi.slcp
@@ -0,0 +1,61 @@
+# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file.
+project_name: mikroe_pressure3_dps310_spi
+label: Third Party Hardware Drivers - DPS310 - Pressure 3 click (Mikroe) - SPI
+description: |
+ This example project shows an example for DPS310 - Pressure 3 click board driver integration on SPI communication.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_pressure3_dps310/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: device_init
+- id: i2cspm
+ instance: [mikroe]
+- id: spidrv
+ instance: [mikroe]
+- id: iostream_usart
+ instance: [vcom]
+- id: app_log
+- id: sleeptimer
+- id: mikroe_pressure3_spi
+ from: third_party_hw_drivers
+toolchain_settings:
+ - option: gcc_linker_option
+ value: "-u _printf_float"
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+configuration:
+ - name: SL_SPIDRV_MIKROE_CS_CONTROL
+ value: "spidrvCsControlApplication"
+other_file:
+ - path: ../../documentation/example/mikroe_pressure3_dps310/image/create_example.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pressure3_dps310/image/hardware_connection.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pressure3_dps310/image/log.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pressure3_dps310/image/float.png
+ directory: "image"
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_pwm_driver_si8711cc/app.c b/app/example/mikroe_pwm_driver_si8711cc/app.c
new file mode 100644
index 00000000..7fb76809
--- /dev/null
+++ b/app/example/mikroe_pwm_driver_si8711cc/app.c
@@ -0,0 +1,91 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+#include "app_log.h"
+#include "sl_pwm_instances.h"
+#include "mikroe_si8711cc.h"
+#include "sl_sleeptimer.h"
+
+static const float DUTY_CYCLE_STEP = 0.1;
+static const uint16_t FREQUENCY = 1000;
+static const uint16_t TIMER_PERIOD = 2000;
+
+static sl_sleeptimer_timer_handle_t app_timer_handle;
+static volatile bool timer_trigger = false;
+static uint8_t step_count = 1;
+static float duty_cycle;
+
+void app_timer_callback(sl_sleeptimer_timer_handle_t *handle, void *data);
+
+void app_init(void)
+{
+ app_log("Hello World - PWM Driver Click !!!\r\n");
+
+ if (mikroe_si8711cc_init(&sl_pwm_mikroe) == SL_STATUS_OK) {
+ app_log("PWM Driver Click board driver init successfully\r\n");
+
+ sl_status_t stt = sl_sleeptimer_restart_periodic_timer_ms(
+ &app_timer_handle,
+ TIMER_PERIOD,
+ app_timer_callback,
+ NULL,
+ 0,
+ 0);
+
+ app_log("sl_sleeptimer_restart_periodic_timer = 0x%lx\r\n", stt);
+ duty_cycle = step_count * DUTY_CYCLE_STEP;
+ mikroe_si8711cc_set_frequency(FREQUENCY);
+ mikroe_si8711cc_pwm_start();
+
+ app_log("mikroe_si8711cc_pwm_start \r\n");
+ } else {
+ app_log("PWM Driver Click board driver init failed," \
+ " please run program again.\r\n");
+ }
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ if (timer_trigger) {
+ timer_trigger = false;
+
+ mikroe_si8711cc_set_duty_cycle(duty_cycle);
+ app_log("PWM Driver set duty = %d%%\r\n", (uint16_t)(duty_cycle * 100));
+
+ step_count++;
+ duty_cycle = step_count * DUTY_CYCLE_STEP;
+
+ if (step_count >= 10) {
+ step_count = 1;
+ duty_cycle = 0.1;
+ }
+ }
+}
+
+void app_timer_callback(sl_sleeptimer_timer_handle_t *handle, void *data)
+{
+ (void)handle;
+ (void)data;
+
+ timer_trigger = true;
+}
diff --git a/app/example/mikroe_pwm_driver_si8711cc/app.h b/app/example/mikroe_pwm_driver_si8711cc/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_pwm_driver_si8711cc/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_pwm_driver_si8711cc/main.c b/app/example/mikroe_pwm_driver_si8711cc/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_pwm_driver_si8711cc/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_pwm_driver_si8711cc/mikroe_pwm_driver_si8711cc.slcp b/app/example/mikroe_pwm_driver_si8711cc/mikroe_pwm_driver_si8711cc.slcp
new file mode 100644
index 00000000..44879dbf
--- /dev/null
+++ b/app/example/mikroe_pwm_driver_si8711cc/mikroe_pwm_driver_si8711cc.slcp
@@ -0,0 +1,59 @@
+project_name: mikroe_pwm_driver_si8711cc
+label: Third Party Hardware Drivers - SI8711CC - PWM Driver Click (Mikroe)
+description: |
+ This example project shows an example for Third Party Hardware Drivers - SI8711CC - PWM Driver Click (Mikroe) integration.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_pwm_driver_si8711cc/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+config_file:
+component:
+- id: sl_system
+- id: sleeptimer
+- id: app_log
+- id: iostream_usart
+ instance:
+ - vcom
+- id: device_init
+- id: pwm_driver_si8711cc
+ from: third_party_hw_drivers
+configuration:
+toolchain_settings:
+define:
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/mikroe_pwm_driver_si8711cc/image/create_example.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pwm_driver_si8711cc/image/hardware_connection_1.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pwm_driver_si8711cc/image/hardware_connection_2.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pwm_driver_si8711cc/image/log.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pwm_driver_si8711cc/image/result_1.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pwm_driver_si8711cc/image/result_2.png
+ directory: "image"
+ - path: ../../documentation/example/mikroe_pwm_driver_si8711cc/image/result_3.png
+ directory: "image"
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_radar_mm5d91_00/mikroe_radar_mm5d91_00.slcp b/app/example/mikroe_radar_mm5d91_00/mikroe_radar_mm5d91_00.slcp
index 8bbd6162..c54b3cfc 100644
--- a/app/example/mikroe_radar_mm5d91_00/mikroe_radar_mm5d91_00.slcp
+++ b/app/example/mikroe_radar_mm5d91_00/mikroe_radar_mm5d91_00.slcp
@@ -44,7 +44,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_radar_mm5d91_00/hardware_connection.png
- path: ../../documentation/example/mikroe_radar_mm5d91_00/create_example.png
diff --git a/app/example/mikroe_relay2_lca717/mikroe_relay2_lca717.slcp b/app/example/mikroe_relay2_lca717/mikroe_relay2_lca717.slcp
index 00af47f3..d1c0e123 100644
--- a/app/example/mikroe_relay2_lca717/mikroe_relay2_lca717.slcp
+++ b/app/example/mikroe_relay2_lca717/mikroe_relay2_lca717.slcp
@@ -34,7 +34,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_relay2_lca717/hardware_connection.png
- path: ../../documentation/example/mikroe_relay2_lca717/create_example.png
diff --git a/app/example/mikroe_rf_meter_ad8318/app.c b/app/example/mikroe_rf_meter_ad8318/app.c
new file mode 100644
index 00000000..3c7721f1
--- /dev/null
+++ b/app/example/mikroe_rf_meter_ad8318/app.c
@@ -0,0 +1,86 @@
+/***************************************************************************//**
+ * @file app.c
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "mikroe_ad8318.h"
+#include "app_log.h"
+#include "sl_spidrv_instances.h"
+#include "sl_simple_timer.h"
+
+static sl_simple_timer_t rf_meter_timer;
+
+static void application_task(void);
+static void rf_meter_simple_timer_callback(sl_simple_timer_t *timer,
+ void *data);
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+ sl_status_t sc;
+
+ app_log("Application initialization.\n");
+
+ sc = mikroe_ad8318_init(sl_spidrv_mikroe_handle);
+ if (!sc) {
+ app_log("RF Meter Click is initialized.\n");
+ } else {
+ app_log("RF Meter Click initialization is failed!\n");
+ }
+
+ sl_simple_timer_start(&rf_meter_timer,
+ 1000,
+ rf_meter_simple_timer_callback,
+ NULL,
+ true);
+}
+
+/***************************************************************************//**
+ * Application task.
+ ******************************************************************************/
+static void application_task(void)
+{
+ sl_status_t sc;
+ float signal;
+
+ sc = mikroe_ad8318_get_signal_strength(MIKROE_AD8318_DEF_SLOPE,
+ MIKROE_AD8318_DEF_INTERCEPT,
+ &signal);
+ if (!sc) {
+ app_log("Signal strength: %.2f dBm\n", signal);
+ } else {
+ app_log("Reading signal strength is failed!\n");
+ }
+}
+
+/***************************************************************************//**
+ * Simple timer callback function.
+ ******************************************************************************/
+static void rf_meter_simple_timer_callback(sl_simple_timer_t *timer,
+ void *data)
+{
+ (void)timer;
+ (void)data;
+
+ application_task();
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+}
diff --git a/app/example/mikroe_rf_meter_ad8318/app.h b/app/example/mikroe_rf_meter_ad8318/app.h
new file mode 100644
index 00000000..9e860c11
--- /dev/null
+++ b/app/example/mikroe_rf_meter_ad8318/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file app.h
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_rf_meter_ad8318/main.c b/app/example/mikroe_rf_meter_ad8318/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_rf_meter_ad8318/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_rf_meter_ad8318/mikroe_rf_meter_ad8318.slcp b/app/example/mikroe_rf_meter_ad8318/mikroe_rf_meter_ad8318.slcp
new file mode 100644
index 00000000..f927aa9c
--- /dev/null
+++ b/app/example/mikroe_rf_meter_ad8318/mikroe_rf_meter_ad8318.slcp
@@ -0,0 +1,56 @@
+project_name: mirkoe_rf_meter_ad8318
+label: Third Party Hardware Drivers - AD8318 - RF Meter Click (Mikroe)
+description: |
+ This example project shows an example for Mikroe RF Meter Click board driver integration.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_rf_meter_ad8318/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+
+component:
+- id: app_log
+- id: sl_system
+- id: device_init
+- id: simple_timer
+- id: mirkoe_rf_meter
+ from: third_party_hw_drivers
+- id: iostream_eusart
+ instance: [vcom]
+
+toolchain_settings:
+ - option: gcc_linker_option
+ value: "-u _printf_float"
+
+define:
+ - name: DEBUG_EFM
+
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+
+other_file:
+ - path: ../../documentation/example/mikroe_rf_meter_ad8318/create_example.png
+ - path: ../../documentation/example/mikroe_rf_meter_ad8318/hardware_connection.png
+ - path: ../../documentation/example/mikroe_rf_meter_ad8318/console_log.png
+ - path: ../../documentation/example/mikroe_rf_meter_ad8318/install_float.png
+ - path: ../../documentation/example/mikroe_rf_meter_ad8318/software_layer.png
+
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_stepper2_a4988/mikroe_stepper2_a4988.slcp b/app/example/mikroe_stepper2_a4988/mikroe_stepper2_a4988.slcp
index e92848fa..0a1ffc0c 100644
--- a/app/example/mikroe_stepper2_a4988/mikroe_stepper2_a4988.slcp
+++ b/app/example/mikroe_stepper2_a4988/mikroe_stepper2_a4988.slcp
@@ -46,7 +46,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_stepper2_a4988/create_example.png
- path: ../../documentation/example/mikroe_stepper2_a4988/hardware_connection.png
diff --git a/app/example/mikroe_stepper_a3967/app.c b/app/example/mikroe_stepper_a3967/app.c
new file mode 100644
index 00000000..3a082196
--- /dev/null
+++ b/app/example/mikroe_stepper_a3967/app.c
@@ -0,0 +1,70 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "mikroe_a3967.h"
+#include "app_log.h"
+#include "sl_sleeptimer.h"
+
+// The 28BYJ-48 motor features a 1/64 reduction gear set.
+#define MOTOR_GEAR_RATIO 64
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+ sl_status_t sc = SL_STATUS_OK;
+
+ app_log("Stepper Click demo application!!!\r\n");
+
+ // specifications of the motor
+ mikroe_a3967_init();
+ mikroe_a3967_set_direction(MIKROE_A3967_CLOCKWISE);
+ mikroe_a3967_set_step_frequency(500);
+ mikroe_a3967_config_mode(MIKROE_A3967_FULL_STEP);
+
+ app_log("A3967 Stepper Start\r\n");
+
+ // The 28BYJ-48 motor have 64 steps per revolution.
+ // So it need (64 * MOTOR_GEAR_RATIO) step to complete one revolution.
+ sc = mikroe_a3967_step(16 * MOTOR_GEAR_RATIO);
+ if (sc != SL_STATUS_OK) {
+ app_log("error code = 0x%lx\r\n", sc);
+ }
+
+ // Need to wait until the motor stop
+ while (mikroe_a3967_get_state()) {}
+ mikroe_a3967_set_direction(MIKROE_A3967_COUNTERCLOCKWISE);
+ sc = mikroe_a3967_step(32 * MOTOR_GEAR_RATIO);
+ if (sc != SL_STATUS_OK) {
+ app_log("error code = 0x%lx\r\n", sc);
+ }
+
+ // Need to wait until the motor stop
+ while (mikroe_a3967_get_state()) {}
+ mikroe_a3967_set_direction(MIKROE_A3967_CLOCKWISE);
+ sc = mikroe_a3967_step(64 * MOTOR_GEAR_RATIO);
+ if (sc != SL_STATUS_OK) {
+ app_log("error code = 0x%lx\r\n", sc);
+ }
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+}
diff --git a/app/example/mikroe_stepper_a3967/app.h b/app/example/mikroe_stepper_a3967/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/mikroe_stepper_a3967/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/mikroe_stepper_a3967/main.c b/app/example/mikroe_stepper_a3967/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/mikroe_stepper_a3967/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/mikroe_stepper_a3967/mikroe_stepper_a3967.slcp b/app/example/mikroe_stepper_a3967/mikroe_stepper_a3967.slcp
new file mode 100644
index 00000000..15736f2d
--- /dev/null
+++ b/app/example/mikroe_stepper_a3967/mikroe_stepper_a3967.slcp
@@ -0,0 +1,47 @@
+project_name: mikroe_stepper_a3967
+label: Third Party Hardware Drivers - A3967 - Stepper Click (Mikroe)
+description: |
+ This example project shows an example for Third Party Hardware Drivers - A3967 - Stepper Click (Mikroe) integration.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/mikroe_stepper_a3967/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: device_init
+- id: mikroe_stepper_a3967
+ from: third_party_hw_drivers
+- id: iostream_usart
+ instance: [vcom]
+- id: app_log
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/mikroe_stepper_a3967/image/create_example.png
+ directory: image
+ - path: ../../documentation/example/mikroe_stepper_a3967/image/hardware_connection.png
+ directory: image
+ - path: ../../documentation/example/mikroe_stepper_a3967/image/test.gif
+ directory: image
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/mikroe_temphum15_sht40/mikroe_temphum15_sht40.slcp b/app/example/mikroe_temphum15_sht40/mikroe_temphum15_sht40.slcp
index 5147feda..2a5bd8a5 100644
--- a/app/example/mikroe_temphum15_sht40/mikroe_temphum15_sht40.slcp
+++ b/app/example/mikroe_temphum15_sht40/mikroe_temphum15_sht40.slcp
@@ -41,7 +41,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_temphum15_sht40/create_example.png
- path: ../../documentation/example/mikroe_temphum15_sht40/hardware_connection.png
diff --git a/app/example/mikroe_temphum9_shtc3/mikroe_temphum9_shtc3.slcp b/app/example/mikroe_temphum9_shtc3/mikroe_temphum9_shtc3.slcp
index b311eb32..c582cd15 100644
--- a/app/example/mikroe_temphum9_shtc3/mikroe_temphum9_shtc3.slcp
+++ b/app/example/mikroe_temphum9_shtc3/mikroe_temphum9_shtc3.slcp
@@ -41,7 +41,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_temphum9_shtc3/create_example.png
- path: ../../documentation/example/mikroe_temphum9_shtc3/hardware_connection.png
diff --git a/app/example/mikroe_utm7segr_max6969/mikroe_utm7segr_max6969.slcp b/app/example/mikroe_utm7segr_max6969/mikroe_utm7segr_max6969.slcp
index 6d3279a3..db277a5d 100644
--- a/app/example/mikroe_utm7segr_max6969/mikroe_utm7segr_max6969.slcp
+++ b/app/example/mikroe_utm7segr_max6969/mikroe_utm7segr_max6969.slcp
@@ -47,7 +47,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
ui_hints:
highlight:
- path: README.md
diff --git a/app/example/mikroe_water_detect/mikroe_water_detect.slcp b/app/example/mikroe_water_detect/mikroe_water_detect.slcp
index 68bf48df..68b885ac 100644
--- a/app/example/mikroe_water_detect/mikroe_water_detect.slcp
+++ b/app/example/mikroe_water_detect/mikroe_water_detect.slcp
@@ -38,7 +38,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/mikroe_water_detect/create_example.png
- path: ../../documentation/example/mikroe_water_detect/hardware_connection.png
diff --git a/app/example/silabs_ir_generate/app.c b/app/example/silabs_ir_generate/app.c
new file mode 100644
index 00000000..91bb8ede
--- /dev/null
+++ b/app/example/silabs_ir_generate/app.c
@@ -0,0 +1,108 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+#include
+#include "em_device.h"
+#include "em_chip.h"
+#include "em_timer.h"
+#include "em_cmu.h"
+#include "em_emu.h"
+#include "app_log.h"
+#include "ir_generate.h"
+
+volatile uint16_t timer_1ms = 0;
+static bool repeat_flag = false;
+static uint8_t restart_conter = 0;
+void TIMER2_init(void);
+void TIMER2_IRQHandler(void);
+
+void TIMER2_IRQHandler(void)
+{
+ // Acknowledge the interrupt
+ uint32_t flags = TIMER_IntGet(TIMER2);
+ TIMER_IntClear(TIMER2, flags);
+ timer_1ms++;
+}
+
+void TIMER2_init(void)
+{
+ uint32_t timerFreq = 0;
+
+ CMU_ClockEnable(cmuClock_TIMER2, true);
+
+ // Initialize the timer
+ TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
+ timerInit.prescale = timerPrescale2;
+ timerInit.enable = false;
+
+ // Configure but do not start the timer
+ TIMER_Init(TIMER2, &timerInit);
+
+ timerFreq = CMU_ClockFreqGet(cmuClock_TIMER2) / (timerInit.prescale + 1);
+ TIMER_TopSet(TIMER2, (timerFreq / 1000));// 1000 for 1ms, 200 for 5ms
+
+ // Start the timer
+ TIMER_Enable(TIMER2, true);
+
+ // Enable TIMER2 compare event interrupts to update the duty cycle
+ TIMER_IntEnable(TIMER2, TIMER_IF_OF);
+ NVIC_EnableIRQ(TIMER2_IRQn);
+}
+
+/**
+ * @brief ir sent callback
+ *
+ * @param none
+ *
+ * @return none
+ *
+ */
+void app_ir_complete(void)
+{
+ app_log("ir complete\r\n");
+}
+
+void app_init(void)
+{
+ TIMER2_init();
+ app_log("test ir\r\n");
+
+ ir_generate_init(CODE_NEC, app_ir_complete);
+
+ // ir_generate_stream(0xFF, 0xFF, false); // for test
+}
+
+void app_process_action(void)
+{
+ uint8_t frame_interval[2] = { 108, 45 }; // 108 for NEC, 45 for SONY
+
+ if (timer_1ms >= frame_interval[CODE_NEC]) {
+ timer_1ms -= frame_interval[CODE_NEC];
+
+ ir_generate_stream(0xFF, 0xFF, repeat_flag); // for test
+
+ // for NEC protocol, change after 4th repeat frame.
+ if (restart_conter++ % 5 == 0) {
+ repeat_flag = false;
+ } else {
+ repeat_flag = true;
+ }
+ }
+}
diff --git a/app/example/silabs_ir_generate/app.h b/app/example/silabs_ir_generate/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/silabs_ir_generate/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/silabs_ir_generate/main.c b/app/example/silabs_ir_generate/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/silabs_ir_generate/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/silabs_ir_generate/silabs_ir_generate.slcp b/app/example/silabs_ir_generate/silabs_ir_generate.slcp
new file mode 100644
index 00000000..8d6a6b10
--- /dev/null
+++ b/app/example/silabs_ir_generate/silabs_ir_generate.slcp
@@ -0,0 +1,59 @@
+project_name: silabs_ir_generate
+label: Third Party Hardware Drivers - IR Generate (Silabs)
+description: |
+ This example project shows an example for implementation of IR generator driver.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/silabs_ir_generate/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: device_init
+- id: iostream_usart
+ instance: [vcom]
+- id: app_log
+- id: silabs_ir_generate
+ from: third_party_hw_drivers
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/silabs_ir_generate/image/create_example.png
+ directory: "image"
+ - path: ../../documentation/example/silabs_ir_generate/image/hardware_connection.png
+ directory: "image"
+ - path: ../../documentation/example/silabs_ir_generate/image/log.png
+ directory: "image"
+ - path: ../../documentation/example/silabs_ir_generate/image/default_config.png
+ directory: "image"
+ - path: ../../documentation/example/silabs_ir_generate/image/IR_API.png
+ directory: "image"
+ - path: ../../documentation/example/silabs_ir_generate/image/IR_workflow.png
+ directory: "image"
+
+configuration:
+- name: SL_BOARD_ENABLE_VCOM
+ value: "1"
+ condition:
+ - iostream_usart
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/silabs_pir_ira_s210st01/app.c b/app/example/silabs_pir_ira_s210st01/app.c
new file mode 100644
index 00000000..9a7b5870
--- /dev/null
+++ b/app/example/silabs_pir_ira_s210st01/app.c
@@ -0,0 +1,103 @@
+/***************************************************************************//**
+ * @file
+ * @brief PIR driver simple example.
+ *******************************************************************************
+ * # License
+ * Copyright 2019 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include
+#include
+#include
+
+#include "em_device.h"
+#include "em_chip.h"
+#include "em_gpio.h"
+#include "em_emu.h"
+
+#include "sl_simple_led.h"
+#include "sl_simple_led_instances.h"
+
+#include
+#define QUEUE_LENGTH 4
+
+static pir_sample_t pir_queue[QUEUE_LENGTH]; // User defined sample queue
+static volatile bool adc_int = false; // ADC interrupt flag
+
+/***************************************************************************//**
+ * @brief
+ * Motion detection callback
+ *
+ * @note
+ * Use the LED on Occupancy-Sensor-EXP board to indicate motion on/off
+ ******************************************************************************/
+static void pir_motion_detect_callback(bool motion_status)
+{
+ if (motion_status) {
+ sl_led_turn_on(SL_SIMPLE_LED_INSTANCE(0));
+ } else {
+ sl_led_turn_off(SL_SIMPLE_LED_INSTANCE(0));
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * ADC IRQ callback
+ ******************************************************************************/
+static void pir_adc_irq_callback(void)
+{
+ adc_int = true;
+}
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+ // Initialize PIR
+ pir_init_t pir = PIR_INIT_DEFAULT;
+ pir.opamp_mode = pir_opamp_mode_external;
+ pir.motion_detection_callback = pir_motion_detect_callback;
+ pir.sample_queue_size = QUEUE_LENGTH;
+ pir.sample_queue = pir_queue;
+ pir.use_timestamp = true;
+ pir.adc_irq_callback = pir_adc_irq_callback;
+ pir_init(&pir, true);
+
+ // Start PIR
+ pir_start();
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ // Infinite loop
+ if (adc_int) {
+ adc_int = false;
+ // Run motion detection algorithm
+ pir_detect_motion();
+ // Debug PIR samples if necessary
+ while (1) {
+ uint16_t size = 0;
+
+ if ((SL_STATUS_OK == pir_get_queue_size(&size)) && (size > 0)) {
+ pir_sample_t sample;
+
+ pir_read_queue(&sample);
+ } else {
+ break;
+ }
+ }
+ }
+ EMU_EnterEM2(true);
+}
diff --git a/app/example/silabs_pir_ira_s210st01/app.h b/app/example/silabs_pir_ira_s210st01/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/silabs_pir_ira_s210st01/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/silabs_pir_ira_s210st01/main.c b/app/example/silabs_pir_ira_s210st01/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/silabs_pir_ira_s210st01/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/silabs_pir_ira_s210st01/silabs_pir_ira_s210st01.slcp b/app/example/silabs_pir_ira_s210st01/silabs_pir_ira_s210st01.slcp
new file mode 100644
index 00000000..a4286843
--- /dev/null
+++ b/app/example/silabs_pir_ira_s210st01/silabs_pir_ira_s210st01.slcp
@@ -0,0 +1,46 @@
+# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file.
+project_name: silabs_pir_ira_s210st01
+label: Third Party Hardware Drivers - IRA-S210ST01 - PIR Sensor (Silabs)
+description: |
+ This example project shows an example for PIR sensor on the occupancy sensor EXP board driver integration.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/silabs_pir_ira_s210st01/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: silabs_pir_ira_s210st01
+ from: third_party_hw_drivers
+- id: device_init
+- id: simple_led
+ instance: [led0]
+other_file:
+- path: ../../documentation/example/silabs_pir_ira_s210st01/create_example.png
+- path: ../../documentation/example/silabs_pir_ira_s210st01/api.png
+- path: ../../documentation/example/silabs_pir_ira_s210st01/peripherals.png
+- path: ../../documentation/example/silabs_pir_ira_s210st01/workflow.png
+- path: ../../documentation/example/silabs_pir_ira_s210st01/hardware_connection.png
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/silabs_triac/app.c b/app/example/silabs_triac/app.c
new file mode 100644
index 00000000..3028e038
--- /dev/null
+++ b/app/example/silabs_triac/app.c
@@ -0,0 +1,142 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "em_letimer.h"
+#include "em_gpio.h"
+#include "em_emu.h"
+#include "em_cmu.h"
+
+#include "sl_simple_button_instances.h"
+#include "triacdrv.h"
+
+/*
+ * Using the LFXO for the LETIMER clock, 32768/120 = 273.066666. Note
+ * that the output low/high time has to be half of one 60 Hz period,
+ * thus the 120 Hz output overflow frequency for the LETIMER. Use 273
+ * for the counter top value. Use 328 to get a 50 Hz output.
+ */
+#define LETIMER_TOP 273
+
+// Duty cycle value
+uint32_t triacDuty; // initially off
+
+/**************************************************************************//**
+ * @brief
+ * Initialize the LETIMER to output a 50/60 Hz square wave for testing.
+ *****************************************************************************/
+void letimerLineHz(void)
+{
+ LETIMER_Init_TypeDef letimerInit = LETIMER_INIT_DEFAULT;
+
+ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);
+
+ CMU_ClockEnable(cmuClock_LETIMER0, true);
+
+ // Enable LETIMER0 output0 on PC14 (EXP header pin 12)
+ LETIMER0->ROUTEPEN |= LETIMER_ROUTEPEN_OUT0PEN;
+ LETIMER0->ROUTELOC0 = LETIMER_ROUTELOC0_OUT0LOC_LOC5;
+
+ // Reload COMP0 on underflow, pulse output, and run in repeat mode
+ letimerInit.comp0Top = true;
+ letimerInit.ufoa0 = letimerUFOAToggle;
+ letimerInit.topValue = LETIMER_TOP;
+
+ // Need REP0 != 0 to pulse on underflow
+ LETIMER_RepeatSet(LETIMER0, 0, 1);
+
+ // Initialize and enable LETIMER
+ LETIMER_Init(LETIMER0, &letimerInit);
+}
+
+void initGPIO(void)
+{
+ CMU_ClockEnable(cmuClock_GPIO, true);
+
+ /*
+ * Use minimum slew rate alternate setting for port C pins. This
+ * results in a 100 ns rise/fall time when viewed on a scope. The
+ * default primary slew rate of 5 is retained for other puns.
+ */
+ GPIO_SlewrateSet(gpioPortC, 5, 0);
+ GPIO_PinModeSet(gpioPortC, 14, gpioModePushPullAlternate, 0);
+}
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+ TRIACDRV_Init_TypeDef triacInit = TRIAC_INIT_DEFAULT;
+
+ initGPIO();
+
+ letimerLineHz();
+
+ triacInit.acmpInput = acmpInputAPORT0YCH0; // PC0, EXP header pin 3
+ triacInit.acmpPrsChannel = 3;
+ triacInit.timerPrsBaseChannel = 4;
+ triacInit.timerPrsOutputPort = gpioPortC;
+ triacInit.timerPrsOutputPin = 8;
+ triacInit.timerPrsOutputLoc = 0; // PC8, EXP header pin 10
+ triacInit.pulseWidth = TRIACDRV_MAX_ENABLE_PULSE_WIDTH;
+
+ // Halt if initialization fails
+ if (triacdrv_init(&triacInit) != SL_STATUS_OK) {
+ __BKPT(0);
+ }
+
+ // Set initial duty cycle
+ triacDuty = 25;
+ triacdrv_set_duty_cycle(triacDuty);
+
+ // Calibrate
+ triacdrv_calibrate(60);
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ // Sit in EM1 and wait for button presses
+ EMU_EnterEM1();
+}
+
+/***************************************************************************//**
+ * Callback on button change.
+ ******************************************************************************/
+void sl_button_on_change(const sl_button_t *handle)
+{
+ if (sl_button_get_state(handle) == SL_SIMPLE_BUTTON_PRESSED) {
+ if (&sl_button_btn0 == handle) {
+ // PB0 pressed; reduce duty cycle by 5%
+ if (triacDuty > 0) {
+ triacDuty -= 5;
+ } else {
+ triacDuty = 0;
+ }
+ } else if (&sl_button_btn1 == handle) {
+ // PB1 pressed; increase duty cycle by 5%
+ if (triacDuty < 100) {
+ triacDuty += 5;
+ } else {
+ triacDuty = 100;
+ }
+ }
+
+ triacdrv_set_duty_cycle(triacDuty);
+ }
+}
diff --git a/app/example/silabs_triac/app.h b/app/example/silabs_triac/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/silabs_triac/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/silabs_triac/main.c b/app/example/silabs_triac/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/silabs_triac/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/silabs_triac/silabs_triac.slcp b/app/example/silabs_triac/silabs_triac.slcp
new file mode 100644
index 00000000..dc6d481c
--- /dev/null
+++ b/app/example/silabs_triac/silabs_triac.slcp
@@ -0,0 +1,53 @@
+project_name: silabs_triac
+label: Third Party Hardware Drivers - Triac Driver (Silabs)
+description: |
+ This example project shows an example for using TRIAC driver.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/silabs_triac/README.md
+source:
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: device_init
+- id: emlib_letimer
+- id: simple_button
+ instance: [btn0, btn1]
+- id: silabs_triac
+ from: third_party_hw_drivers
+define:
+- name: DEBUG_EFM
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/silabs_triac/image/create_example.png
+ directory: "image"
+ - path: ../../documentation/example/silabs_triac/image/triacdrv_ac_sine.png
+ directory: "image"
+ - path: ../../documentation/example/silabs_triac/image/triacdrv_diagram.png
+ directory: "image"
+ - path: ../../documentation/example/silabs_triac/image/triacdrv_offset_sine.png
+ directory: "image"
+ - path: ../../documentation/example/silabs_triac/image/triacdrv_rectified_sine.png
+ directory: "image"
+ - path: ../../documentation/example/silabs_triac/image/oscilloscope_output.png
+ directory: "image"
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
\ No newline at end of file
diff --git a/app/example/sparkfun_accelerometer_mma8452q/sparkfun_accelerometer_mma8452q.slcp b/app/example/sparkfun_accelerometer_mma8452q/sparkfun_accelerometer_mma8452q.slcp
index 7693dba7..5f6b8588 100644
--- a/app/example/sparkfun_accelerometer_mma8452q/sparkfun_accelerometer_mma8452q.slcp
+++ b/app/example/sparkfun_accelerometer_mma8452q/sparkfun_accelerometer_mma8452q.slcp
@@ -40,7 +40,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_accelerometer_mma8452q/api_overview.png
- path: ../../documentation/example/sparkfun_accelerometer_mma8452q/basic_reading.png
diff --git a/app/example/sparkfun_air_quality_sgp40/sparkfun_air_quality_sgp40.slcp b/app/example/sparkfun_air_quality_sgp40/sparkfun_air_quality_sgp40.slcp
index 784b3473..0582652d 100644
--- a/app/example/sparkfun_air_quality_sgp40/sparkfun_air_quality_sgp40.slcp
+++ b/app/example/sparkfun_air_quality_sgp40/sparkfun_air_quality_sgp40.slcp
@@ -36,7 +36,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_air_quality_sgp40/create_example.png
- path: ../../documentation/example/sparkfun_air_quality_sgp40/hardware_connection.png
diff --git a/app/example/sparkfun_distance_vl53l1x/sparkfun_distance_vl53l1x.slcp b/app/example/sparkfun_distance_vl53l1x/sparkfun_distance_vl53l1x.slcp
index 5b985b84..d3f8ce75 100644
--- a/app/example/sparkfun_distance_vl53l1x/sparkfun_distance_vl53l1x.slcp
+++ b/app/example/sparkfun_distance_vl53l1x/sparkfun_distance_vl53l1x.slcp
@@ -42,7 +42,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_distance_vl53l1x/create_example.png
- path: ../../documentation/example/sparkfun_distance_vl53l1x/connection.png
diff --git a/app/example/sparkfun_dosimeter_type5/sparkfun_dosimeter_type5.slcp b/app/example/sparkfun_dosimeter_type5/sparkfun_dosimeter_type5.slcp
index e791f21c..64f686ae 100644
--- a/app/example/sparkfun_dosimeter_type5/sparkfun_dosimeter_type5.slcp
+++ b/app/example/sparkfun_dosimeter_type5/sparkfun_dosimeter_type5.slcp
@@ -39,7 +39,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_dosimeter_type5/log.png
- path: ../../documentation/example/sparkfun_dosimeter_type5/create_example.png
diff --git a/app/example/sparkfun_environmental_bme280_ccs811/sparkfun_environmental_bme280_ccs811.slcp b/app/example/sparkfun_environmental_bme280_ccs811/sparkfun_environmental_bme280_ccs811.slcp
index e107e4b6..e22b4cdc 100644
--- a/app/example/sparkfun_environmental_bme280_ccs811/sparkfun_environmental_bme280_ccs811.slcp
+++ b/app/example/sparkfun_environmental_bme280_ccs811/sparkfun_environmental_bme280_ccs811.slcp
@@ -43,7 +43,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file: []
ui_hints:
highlight:
diff --git a/app/example/sparkfun_hr_po_max30101_max32664/sparkfun_hr_po_max30101_max32664.slcp b/app/example/sparkfun_hr_po_max30101_max32664/sparkfun_hr_po_max30101_max32664.slcp
index 8eab8ece..c2ba1680 100644
--- a/app/example/sparkfun_hr_po_max30101_max32664/sparkfun_hr_po_max30101_max32664.slcp
+++ b/app/example/sparkfun_hr_po_max30101_max32664/sparkfun_hr_po_max30101_max32664.slcp
@@ -36,7 +36,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_hr_po_max30101_max32664/image/create_example.png
directory: "image"
diff --git a/app/example/sparkfun_human_presence_ak9753/sparkfun_human_presence_ak9753.slcp b/app/example/sparkfun_human_presence_ak9753/sparkfun_human_presence_ak9753.slcp
index dc6b2c4a..4054fbe5 100644
--- a/app/example/sparkfun_human_presence_ak9753/sparkfun_human_presence_ak9753.slcp
+++ b/app/example/sparkfun_human_presence_ak9753/sparkfun_human_presence_ak9753.slcp
@@ -42,7 +42,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_human_presence_ak9753/create_example.png
- path: ../../documentation/example/sparkfun_human_presence_ak9753/hardware_connection.png
diff --git a/app/example/sparkfun_ir_array_amg88xx/app.c b/app/example/sparkfun_ir_array_amg88xx/app.c
new file mode 100644
index 00000000..492601f3
--- /dev/null
+++ b/app/example/sparkfun_ir_array_amg88xx/app.c
@@ -0,0 +1,56 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#include "sl_cli_command.h"
+#include "sl_cli_handles.h"
+#include "ir_array_amg88xx.h"
+#include "sl_i2cspm_instances.h"
+
+extern const sl_cli_command_entry_t app_cli_command_table[];
+
+extern sl_cli_handle_t sl_cli_vcom_handle;
+extern sl_cli_command_group_t sl_cli_vcom_command_group;
+
+sl_cli_command_group_t sl_cli_app_command_group =
+{
+ { NULL },
+ false,
+ app_cli_command_table
+};
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void)
+{
+ amg88xx_init(sl_i2cspm_qwiic, AMG88XX_ADDRESS_OPEN, CELSIUS);
+ // Remove unused autogen CLI command group
+ sl_cli_command_remove_command_group(sl_cli_vcom_handle,
+ &sl_cli_vcom_command_group);
+
+ // Add application CLI commands
+ sl_cli_command_add_command_group(sl_cli_vcom_handle,
+ &sl_cli_app_command_group);
+}
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void)
+{
+ //
+}
diff --git a/app/example/sparkfun_ir_array_amg88xx/app.h b/app/example/sparkfun_ir_array_amg88xx/app.h
new file mode 100644
index 00000000..02bedf57
--- /dev/null
+++ b/app/example/sparkfun_ir_array_amg88xx/app.h
@@ -0,0 +1,31 @@
+/***************************************************************************//**
+ * @file
+ * @brief Top level application functions
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+/***************************************************************************//**
+ * Initialize application.
+ ******************************************************************************/
+void app_init(void);
+
+/***************************************************************************//**
+ * App ticking function.
+ ******************************************************************************/
+void app_process_action(void);
+
+#endif // APP_H
diff --git a/app/example/sparkfun_ir_array_amg88xx/app_cli_command_table.c b/app/example/sparkfun_ir_array_amg88xx/app_cli_command_table.c
new file mode 100644
index 00000000..387d1167
--- /dev/null
+++ b/app/example/sparkfun_ir_array_amg88xx/app_cli_command_table.c
@@ -0,0 +1,168 @@
+/***************************************************************************//**
+ * @file sl_cli_command_table.c
+ * @brief Declarations of relevant command structs for cli framework.
+ * @version x.y.z
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+
+#include
+
+#include "sl_cli_config.h"
+#include "sl_cli_command.h"
+#include "sl_cli_arguments.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Provide function declarations
+void app_set_tempereture_scale(sl_cli_command_arg_t *arguments);
+void app_get_thermistor_temperature(sl_cli_command_arg_t *arguments);
+void app_get_thermistor_temperature_raw(sl_cli_command_arg_t *arguments);
+void app_get_sensor_array_temperatures(sl_cli_command_arg_t *arguments);
+void app_get_sensor_array_temperatures_raw(sl_cli_command_arg_t *arguments);
+void app_sensor_wakeup(sl_cli_command_arg_t *arguments);
+void app_sensor_sleep(sl_cli_command_arg_t *arguments);
+void app_sensor_60_sec_standby(sl_cli_command_arg_t *arguments);
+void app_sensor_10_sec_standby(sl_cli_command_arg_t *arguments);
+void app_sensor_enable_moving_average(sl_cli_command_arg_t *arguments);
+void app_sensor_disable_moving_average(sl_cli_command_arg_t *arguments);
+
+// Command structs. Names are in the format : cli_cmd_{command group
+// name}_{command name}
+// In order to support hyphen in command and group name, every occurence of it
+// while
+// building struct names will be replaced by "_hyphen_"
+static const sl_cli_command_info_t cli_cmd_set_temp_scale = \
+ SL_CLI_COMMAND(app_set_tempereture_scale,
+ "Set sensor temperature scale",
+ "temperature unit (C or F)" SL_CLI_UNIT_SEPARATOR,
+ { SL_CLI_ARG_STRING, SL_CLI_ARG_END, });
+
+static const sl_cli_command_info_t cli_cmd_get_thermistor_temeprature = \
+ SL_CLI_COMMAND(app_get_thermistor_temperature,
+ "Get thermistor temperature value",
+ "",
+ { SL_CLI_ARG_END, });
+
+static const sl_cli_command_info_t cli_cmd_get_thermistor_temeprature_raw = \
+ SL_CLI_COMMAND(app_get_thermistor_temperature_raw,
+ "Get thermistor temperature in raw conversion",
+ "",
+ { SL_CLI_ARG_END, });
+
+static const sl_cli_command_info_t cli_cmd_get_sensor_array_temepratures = \
+ SL_CLI_COMMAND(app_get_sensor_array_temperatures,
+ "Get sensor array temperature values",
+ "",
+ { SL_CLI_ARG_END, });
+
+static const sl_cli_command_info_t cli_cmd_get_sensor_array_temepratures_raw = \
+ SL_CLI_COMMAND(app_get_sensor_array_temperatures_raw,
+ "Get sensor array temperature values in raw conversion",
+ "",
+ { SL_CLI_ARG_END, });
+
+static const sl_cli_command_info_t cli_cmd_sensor_wakeup = \
+ SL_CLI_COMMAND(app_sensor_wakeup,
+ "Puts the device to normal mode from any other state.",
+ "",
+ { SL_CLI_ARG_END, });
+
+static const sl_cli_command_info_t cli_cmd_sensor_sleep = \
+ SL_CLI_COMMAND(app_sensor_sleep,
+ "Puts device into sleep mode.",
+ "",
+ { SL_CLI_ARG_END, });
+
+static const sl_cli_command_info_t cli_cmd_sensor_60_sec_standby = \
+ SL_CLI_COMMAND(app_sensor_60_sec_standby,
+ "Puts the device into 60 sec update interval mode.",
+ "",
+ { SL_CLI_ARG_END, });
+
+static const sl_cli_command_info_t cli_cmd_sensor_10_sec_standby = \
+ SL_CLI_COMMAND(app_sensor_10_sec_standby,
+ "Puts the device into 10 sec update interval mode.",
+ "",
+ { SL_CLI_ARG_END, });
+
+static const sl_cli_command_info_t cli_cmd_sensor_enable_moving_average = \
+ SL_CLI_COMMAND(app_sensor_enable_moving_average,
+ "Enable \"Twice Moving Average\" ",
+ "",
+ { SL_CLI_ARG_END, });
+static const sl_cli_command_info_t cli_cmd_sensor_disable_moving_average = \
+ SL_CLI_COMMAND(app_sensor_disable_moving_average,
+ "Disable \"Twice Moving Average\" ",
+ "",
+ { SL_CLI_ARG_END, });
+
+// Create group command tables and structs if cli_groups given
+// in template. Group name is suffixed with _group_table for tables
+// and group commands are cli_cmd_( group name )_group
+static const sl_cli_command_entry_t moving_average_group_table[] = {
+ { "enable", &cli_cmd_sensor_enable_moving_average, false },
+ { "disable", &cli_cmd_sensor_disable_moving_average, false },
+ { NULL, NULL, false },
+};
+
+static const sl_cli_command_info_t cli_cmd_moving_average_group = \
+ SL_CLI_COMMAND_GROUP(moving_average_group_table, "");
+
+static const sl_cli_command_entry_t control_group_table[] = {
+ { "wake", &cli_cmd_sensor_wakeup, false },
+ { "sleep", &cli_cmd_sensor_sleep, false },
+ { "60s", &cli_cmd_sensor_60_sec_standby, false },
+ { "10s", &cli_cmd_sensor_10_sec_standby, false },
+ { "moving_average", &cli_cmd_moving_average_group, false },
+ { NULL, NULL, false },
+};
+static const sl_cli_command_info_t cli_cmd_control_group = \
+ SL_CLI_COMMAND_GROUP(control_group_table, "");
+
+static const sl_cli_command_entry_t temperature_group_table[] = {
+ { "set_scale", &cli_cmd_set_temp_scale, false },
+ { "scaled", &cli_cmd_get_thermistor_temeprature, false },
+ { "raw", &cli_cmd_get_thermistor_temeprature_raw, false },
+ { "array", &cli_cmd_get_sensor_array_temepratures, false },
+ { "array_raw", &cli_cmd_get_sensor_array_temepratures_raw, false },
+ { NULL, NULL, false },
+};
+static const sl_cli_command_info_t cli_cmd_temperature_group = \
+ SL_CLI_COMMAND_GROUP(temperature_group_table, "");
+
+// Create root command table
+const sl_cli_command_entry_t app_cli_command_table[] = {
+ { "control", &cli_cmd_control_group, false },
+ { "temperature", &cli_cmd_temperature_group, false },
+ { NULL, NULL, false },
+};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/app/example/sparkfun_ir_array_amg88xx/app_ir_array_cli_cmds.c b/app/example/sparkfun_ir_array_amg88xx/app_ir_array_cli_cmds.c
new file mode 100644
index 00000000..4e791b79
--- /dev/null
+++ b/app/example/sparkfun_ir_array_amg88xx/app_ir_array_cli_cmds.c
@@ -0,0 +1,168 @@
+/***************************************************************************//**
+ * @file
+ * @brief app_adc_cli_cmds.c
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#include
+#include "sl_cli.h"
+#include "sl_cli_arguments.h"
+#include "sl_cli_handles.h"
+#include "ir_array_amg88xx.h"
+
+void app_set_tempereture_scale(sl_cli_command_arg_t *arguments)
+{
+ char *str = ((char *)arguments->argv[2]);
+ if ((*str == 'f') || (*str == 'F')) {
+ set_temperature_scale(FAHRENHEIT);
+ } else {
+ set_temperature_scale(CELSIUS);
+ }
+}
+
+void app_get_thermistor_temperature(sl_cli_command_arg_t *arguments)
+{
+ (void)arguments;
+ float temperature = 0;
+ sl_status_t status_msg = SL_STATUS_OK;
+ status_msg = amg88xx_get_thermistor_temperature(&temperature);
+ if (status_msg == SL_STATUS_OK) {
+ printf("Actual_Temperature: %0.3f \n", temperature);
+ } else {
+ printf("Error: %lu \n", status_msg);
+ }
+}
+
+void app_get_thermistor_temperature_raw(sl_cli_command_arg_t *arguments)
+{
+ (void)arguments;
+ int16_t temperature = 0;
+ sl_status_t status_msg = SL_STATUS_OK;
+ status_msg = amg88xx_get_thermistor_temperature_raw(&temperature);
+ if (status_msg == SL_STATUS_OK) {
+ printf("Actual_Temperature: 0x%x \n", temperature);
+ } else {
+ printf("Error: %lu \n", status_msg);
+ }
+}
+
+void app_get_sensor_array_temperatures(sl_cli_command_arg_t *arguments)
+{
+ (void)arguments;
+ float temperature_grid[8][8];
+ int8_t i = 0;
+ int8_t j = 0;
+ I2C_TransferReturn_TypeDef read_result;
+ read_result = amg88xx_get_sensor_array_temperatures(temperature_grid);
+ if (read_result != SL_STATUS_OK) {
+ printf("Error: i2c read failed");
+ } else {
+ while (i < 8)
+ {
+ j = 7;
+ while (j >= 0)
+ {
+ printf("%3.2f, ", temperature_grid[i][j]);
+ j--;
+ }
+ i++;
+ }
+ printf("\n");
+ }
+}
+
+void app_get_sensor_array_temperatures_raw(sl_cli_command_arg_t *arguments)
+{
+ (void)arguments;
+ uint16_t temperature_grid[8][8];
+ int8_t i = 0;
+ int8_t j = 0;
+ I2C_TransferReturn_TypeDef read_result;
+ read_result = amg88xx_get_sensor_array_temperatures_raw(temperature_grid);
+ if (read_result != SL_STATUS_OK) {
+ printf("Error: i2c read failed");
+ } else {
+ while (i < 8)
+ {
+ j = 7;
+ while (j >= 0)
+ {
+ printf("0x%x, ", temperature_grid[i][j]);
+ j--;
+ }
+ i++;
+ }
+ printf("\n");
+ }
+}
+
+void app_sensor_wakeup(sl_cli_command_arg_t *arguments)
+{
+ (void)arguments;
+ sl_status_t status_msg = SL_STATUS_OK;
+ status_msg = amg88xx_wake();
+ if (status_msg != SL_STATUS_OK) {
+ printf("Error: %lu \n", status_msg);
+ }
+}
+
+void app_sensor_sleep(sl_cli_command_arg_t *arguments)
+{
+ (void)arguments;
+ sl_status_t status_msg = SL_STATUS_OK;
+ status_msg = amg88xx_sleep();
+ if (status_msg != SL_STATUS_OK) {
+ printf("Error: %lu \n", status_msg);
+ }
+}
+
+void app_sensor_60_sec_standby(sl_cli_command_arg_t *arguments)
+{
+ (void)arguments;
+ sl_status_t status_msg = SL_STATUS_OK;
+ status_msg = amg88xx_60_sec_standby();
+ if (status_msg != SL_STATUS_OK) {
+ printf("Error: %lu \n", status_msg);
+ }
+}
+
+void app_sensor_10_sec_standby(sl_cli_command_arg_t *arguments)
+{
+ (void)arguments;
+ sl_status_t status_msg = SL_STATUS_OK;
+ status_msg = amg88xx_10_sec_standby();
+ if (status_msg != SL_STATUS_OK) {
+ printf("Error: %lu \n", status_msg);
+ }
+}
+
+void app_sensor_enable_moving_average(sl_cli_command_arg_t *arguments)
+{
+ (void)arguments;
+ sl_status_t status_msg = SL_STATUS_OK;
+ status_msg = amg88xx_enable_moving_average();
+ if (status_msg != SL_STATUS_OK) {
+ printf("Error: %lu \n", status_msg);
+ }
+}
+
+void app_sensor_disable_moving_average(sl_cli_command_arg_t *arguments)
+{
+ (void)arguments;
+ sl_status_t status_msg = SL_STATUS_OK;
+ status_msg = amg88xx_disable_moving_average();
+ if (status_msg != SL_STATUS_OK) {
+ printf("Error: %lu \n", status_msg);
+ }
+}
diff --git a/app/example/sparkfun_ir_array_amg88xx/main.c b/app/example/sparkfun_ir_array_amg88xx/main.c
new file mode 100644
index 00000000..2da253ba
--- /dev/null
+++ b/app/example/sparkfun_ir_array_amg88xx/main.c
@@ -0,0 +1,58 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_system_init.h"
+#include "app.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_system_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_system_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, processing task(s) will be created by
+ // this call.
+ sl_system_init();
+
+ // Initialize the application. For example, create periodic timer(s) or
+ // task(s) if the kernel is present.
+ app_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. Task(s) created in app_init() will start running.
+ sl_system_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+ while (1) {
+ // Do not remove this call: Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_system_process_action();
+
+ // Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/app/example/sparkfun_ir_array_amg88xx/sl_cli_config_vcom.h b/app/example/sparkfun_ir_array_amg88xx/sl_cli_config_vcom.h
new file mode 100644
index 00000000..e7663771
--- /dev/null
+++ b/app/example/sparkfun_ir_array_amg88xx/sl_cli_config_vcom.h
@@ -0,0 +1,132 @@
+/***************************************************************************//**
+ * @file
+ * @brief Configuration file for CLI.
+ * @version x.y.z
+ *******************************************************************************
+ * # License
+ * Copyright 2018 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+
+// <<< Use Configuration Wizard in Context Menu >>>
+
+#ifndef SL_CLI_CONFIG_VCOM_H
+#define SL_CLI_CONFIG_VCOM_H
+
+/*******************************************************************************
+ ****************************** DEFINES ************************************
+ ******************************************************************************/
+
+// CLI instance task priority
+// low + 1
+// low + 2
+// low + 3
+// low + 4
+// low + 5
+// low + 6
+// low + 7
+// below normal
+// below normal + 1
+// below normal + 2
+// below normal + 3
+// below normal + 4
+// below normal + 5
+// below normal + 6
+// below normal + 7
+// normal
+// normal + 1
+// normal + 2
+// normal + 3
+// normal + 4
+// normal + 5
+// normal + 6
+// normal + 7
+// above normal
+// above normal + 1
+// above normal + 2
+// above normal + 3
+// above normal + 4
+// above normal + 5
+// above normal + 6
+// above normal + 7
+// high
+// high + 1
+// high + 2
+// high + 3
+// high + 4
+// high + 5
+// high + 6
+// high + 7
+// realtime
+// realtime + 1
+// realtime + 2
+// realtime + 3
+// realtime + 4
+// realtime + 5
+// realtime + 6
+// realtime + 7
+// Default: osPriorityNormal1
+// Priority of the CLI instance task using the CMSIS order and using the
+// enum name
+#define SL_CLI_VCOM_TASK_PRIORITY osPriorityNormal1
+
+// Task stack size
+// Default: 400
+// Stack size for the CLI task in words.
+#define SL_CLI_VCOM_TASK_STACK_SIZE 400
+
+// CLI task start delay
+// Default: 0
+// Specifies the delay in milliseconds before the cli task start to poll for
+// input.
+#define SL_CLI_VCOM_TASK_START_DELAY_MS 0
+
+// CLI task loop delay
+// Default: 50
+// Specifies the delay in milliseconds after the cli task has polled the
+// input.
+#define SL_CLI_VCOM_TASK_LOOP_DELAY_MS 50
+
+// The iostream handle used by the cli instance
+// Default: sl_iostream_get_default()
+#define SL_CLI_VCOM_IOSTREAM_HANDLE sl_iostream_get_default()
+
+// The default command group.
+// Default: sl_cli_default_command_group.
+// Specifies a pointer to the command group that shall be used as the
+// default command group for the cli instance.
+// The template file that is creating cli instances will also create one
+// command group for each cli instance. During initialization, the
+// sl_cli_default_command_group will be updated for each instance to point
+// to the instance version of the command group. This makes it possible to
+// use the same variable for all instances, but each getting its own
+// command group.
+// The application can provide a group created elsewhere in the
+// application or use an empty definition for no default group.
+// Please note: A command group can only be used once.
+#define SL_CLI_VCOM_COMMAND_GROUP sl_cli_default_command_group
+
+#endif // SL_CLI_CONFIG_VCOM_H
+
+// <<< end of configuration section >>>
diff --git a/app/example/sparkfun_ir_array_amg88xx/sparkfun_ir_array_amg88xx.slcp b/app/example/sparkfun_ir_array_amg88xx/sparkfun_ir_array_amg88xx.slcp
new file mode 100644
index 00000000..8e802eae
--- /dev/null
+++ b/app/example/sparkfun_ir_array_amg88xx/sparkfun_ir_array_amg88xx.slcp
@@ -0,0 +1,65 @@
+# Silicon Labs Project Configuration Tools: slcp, v0, Component selection file.
+project_name: sparkfun_ir_array_amg88xx
+label: Third Party Hardware Drivers - AMG88XX - Grid-EYE Infrared Array Breakout (Sparkfun)
+description: |
+ This example project shows an example for Sparkfun Grid-EYE Infrared Array Breakout board driver integration.
+category: Example|Platform
+filter:
+- name: Device Type
+ value: [SoC]
+- name: MCU
+ value: [32-bit MCU]
+- name: Project Difficulty
+ value: [Beginner]
+package: platform
+quality: evaluation
+readme:
+- path: ../../documentation/example/sparkfun_ir_array_amg88xx/README.md
+source:
+- path: app_cli_command_table.c
+- path: app_ir_array_cli_cmds.c
+- path: app.c
+- path: main.c
+include:
+- path: ''
+ file_list:
+ - path: app.h
+component:
+- id: sl_system
+- id: device_init
+- id: iostream_usart
+ instance: [vcom]
+- id: i2cspm
+ instance: [qwiic]
+- id: cli
+ instance: [vcom]
+- id: sparkfun_ir_array_amg88xx
+ from: third_party_hw_drivers
+config_file:
+ - override:
+ component: cli
+ file_id: sl_cli_config
+ instance: vcom
+ path: sl_cli_config_vcom.h
+configuration:
+ - name: SL_STACK_SIZE
+ value: "10240"
+ - name: SL_HEAP_SIZE
+ value: "6144"
+sdk_extension:
+- id: third_party_hw_drivers
+ version: 1.4.0
+other_file:
+ - path: ../../documentation/example/sparkfun_ir_array_amg88xx/images/create_example.png
+ directory: images
+ - path: ../../documentation/example/sparkfun_ir_array_amg88xx/images/IR_array_struct.png
+ directory: images
+ - path: ../../documentation/example/sparkfun_ir_array_amg88xx/images/dev_kit.jpg
+ directory: images
+ - path: ../../documentation/example/sparkfun_ir_array_amg88xx/images/thermal_image.png
+ directory: images
+ - path: ../../documentation/example/sparkfun_ir_array_amg88xx/temperatue_array_visualiser.py
+ui_hints:
+ highlight:
+ - path: README.md
+ focus: true
diff --git a/app/example/sparkfun_ir_array_mlx90640/sparkfun_ir_array_mlx90640.slcp b/app/example/sparkfun_ir_array_mlx90640/sparkfun_ir_array_mlx90640.slcp
index 22dcef3a..2510ea07 100644
--- a/app/example/sparkfun_ir_array_mlx90640/sparkfun_ir_array_mlx90640.slcp
+++ b/app/example/sparkfun_ir_array_mlx90640/sparkfun_ir_array_mlx90640.slcp
@@ -48,7 +48,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_ir_array_mlx90640/connection.png
- path: ../../documentation/example/sparkfun_ir_array_mlx90640/create_example.png
diff --git a/app/example/sparkfun_micro_oled_ssd1306/sparkfun_micro_oled_ssd1306.slcp b/app/example/sparkfun_micro_oled_ssd1306/sparkfun_micro_oled_ssd1306.slcp
index 8a0a468b..3777a14f 100644
--- a/app/example/sparkfun_micro_oled_ssd1306/sparkfun_micro_oled_ssd1306.slcp
+++ b/app/example/sparkfun_micro_oled_ssd1306/sparkfun_micro_oled_ssd1306.slcp
@@ -44,7 +44,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_micro_oled_ssd1306/bgm220_kit_sparkfun_oled.png
- path: ../../documentation/example/sparkfun_micro_oled_ssd1306/create_example.png
diff --git a/app/example/sparkfun_proximity_vcnl4040/sparkfun_proximity_vcnl4040.slcp b/app/example/sparkfun_proximity_vcnl4040/sparkfun_proximity_vcnl4040.slcp
index 0a0c45e6..e662ec11 100644
--- a/app/example/sparkfun_proximity_vcnl4040/sparkfun_proximity_vcnl4040.slcp
+++ b/app/example/sparkfun_proximity_vcnl4040/sparkfun_proximity_vcnl4040.slcp
@@ -39,7 +39,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_proximity_vcnl4040/connection.png
- path: ../../documentation/example/sparkfun_proximity_vcnl4040/create_example.png
diff --git a/app/example/sparkfun_qwiic_joystick/sparkfun_qwiic_joystick.slcp b/app/example/sparkfun_qwiic_joystick/sparkfun_qwiic_joystick.slcp
index 075d9ad8..d8dfa9aa 100644
--- a/app/example/sparkfun_qwiic_joystick/sparkfun_qwiic_joystick.slcp
+++ b/app/example/sparkfun_qwiic_joystick/sparkfun_qwiic_joystick.slcp
@@ -38,7 +38,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_qwiic_joystick/logs.png
- path: ../../documentation/example/sparkfun_qwiic_joystick/create_example.png
diff --git a/app/example/sparkfun_rfid_id12la/sparkfun_rfid_id12la.slcp b/app/example/sparkfun_rfid_id12la/sparkfun_rfid_id12la.slcp
index 8f31a457..aec18a51 100644
--- a/app/example/sparkfun_rfid_id12la/sparkfun_rfid_id12la.slcp
+++ b/app/example/sparkfun_rfid_id12la/sparkfun_rfid_id12la.slcp
@@ -46,7 +46,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_rfid_id12la/api_overview.png
- path: ../../documentation/example/sparkfun_rfid_id12la/create_example.png
diff --git a/app/example/sparkfun_soil_moisture/sparkfun_soil_moisture.slcp b/app/example/sparkfun_soil_moisture/sparkfun_soil_moisture.slcp
index a531ca20..c024325d 100644
--- a/app/example/sparkfun_soil_moisture/sparkfun_soil_moisture.slcp
+++ b/app/example/sparkfun_soil_moisture/sparkfun_soil_moisture.slcp
@@ -39,7 +39,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_soil_moisture/components.png
- path: ../../documentation/example/sparkfun_soil_moisture/connection.png
diff --git a/app/example/sparkfun_spectroscopy_as7265x/sparkfun_spectroscopy_as7265x.slcp b/app/example/sparkfun_spectroscopy_as7265x/sparkfun_spectroscopy_as7265x.slcp
index 160957cd..7d6107d0 100644
--- a/app/example/sparkfun_spectroscopy_as7265x/sparkfun_spectroscopy_as7265x.slcp
+++ b/app/example/sparkfun_spectroscopy_as7265x/sparkfun_spectroscopy_as7265x.slcp
@@ -42,7 +42,7 @@ define:
- name: DEBUG_EFM
sdk_extension:
- id: third_party_hw_drivers
- version: 1.3.0
+ version: 1.4.0
other_file:
- path: ../../documentation/example/sparkfun_spectroscopy_as7265x/basic_reading.png
- path: ../../documentation/example/sparkfun_spectroscopy_as7265x/basic_reading_with_led.png
diff --git a/driver/component/drivers/mikroe/e_paper_154_inch.slcc b/driver/component/drivers/mikroe/e_paper_154_inch.slcc
new file mode 100644
index 00000000..0679acd3
--- /dev/null
+++ b/driver/component/drivers/mikroe/e_paper_154_inch.slcc
@@ -0,0 +1,44 @@
+id: mikroe_epaper_display_154_inch
+package: third_party_hw_drivers
+label: E-Paper display 1.54" 200x200 dots (Mikroe)
+description: >
+ Driver for the Mikroe eINK Click adaper board with the E-Paper display 1.54" 200x200 dots.
+category: Display & LED
+quality: evaluation
+ui_hints:
+ visibility: basic
+root_path: driver
+requires:
+ - name: status
+ - name: mikroe_peripheral_driver_spi
+provides:
+ - name: oled_display
+config_file:
+ - path: public/mikroe/e_paper_154_inch/config/brd2703a/mikroe_e_paper_154_inch_config.h
+ file_id: mikroe_e_paper_154_inch_config
+ condition: [brd2703a]
+ - path: public/mikroe/e_paper_154_inch/config/brd4108a/mikroe_e_paper_154_inch_config.h
+ file_id: mikroe_e_paper_154_inch_config
+ condition: [brd4108a]
+ - path: public/mikroe/e_paper_154_inch/config/brd4314a/mikroe_e_paper_154_inch_config.h
+ file_id: mikroe_e_paper_154_inch_config
+ condition: [brd4314a]
+
+template_contribution:
+ - name: component_catalog
+ value: mikroe_epaper_display_154_inch
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: thirdparty/mikrosdk_click_v2/clicks/eink154inch/lib/include
+ file_list:
+ - path: eink_154inch.h
+ - path: public/mikroe/e_paper_154_inch/inc
+ file_list:
+ - path: mikroe_e_paper_154_inch.h
+ - path: oled_display.h
+source:
+ - path: thirdparty/mikrosdk_click_v2/clicks/eink154inch/lib/src/eink_154inch.c
+ - path: public/mikroe/e_paper_154_inch/src/mikroe_e_paper_154_inch.c
+ - path: public/mikroe/e_paper_154_inch/src/oled_display.c
diff --git a/driver/component/drivers/mikroe/lte_iot2_bg96.slcc b/driver/component/drivers/mikroe/lte_iot2_bg96.slcc
new file mode 100644
index 00000000..330d319e
--- /dev/null
+++ b/driver/component/drivers/mikroe/lte_iot2_bg96.slcc
@@ -0,0 +1,66 @@
+id: mikroe_lte_iot2
+package: third_party_hw_drivers
+label: BG96 - LTE IoT 2 Click (Mikroe)
+description: >
+ Driver for the Mikroe BG96 - LTE IoT Click board, this board relies on the Quectel BG96 LTE module using UART interface.
+category: Wireless Connectivity
+quality: evaluation
+ui_hints:
+ visibility: basic
+root_path: driver
+requires:
+ - name: status
+ - name: emlib_gpio
+ - name: app_queue
+ - name: sleeptimer
+ - name: iostream_usart
+recommends:
+ - id: iostream_usart
+ instance: [bg96]
+config_file:
+ - path: public/mikroe/lte_iot2_bg96/config/brd2703a/mikroe_lte_iot2_bg96_config.h
+ condition: [brd2703a]
+ - path: public/mikroe/lte_iot2_bg96/config/brd4108a/mikroe_lte_iot2_bg96_config.h
+ condition: [brd4108a]
+ - path: public/mikroe/lte_iot2_bg96/config/brd4314a/mikroe_lte_iot2_bg96_config.h
+ condition: [brd4314a]
+ - override:
+ component: iostream_usart
+ file_id: iostream_usart_config
+ instance: bg96
+ path: public/mikroe/lte_iot2_bg96/config/brd4314a/sl_iostream_usart_bg96_config.h
+ condition: [brd4314a]
+ - override:
+ component: iostream_usart
+ file_id: iostream_usart_config
+ instance: bg96
+ path: public/mikroe/lte_iot2_bg96/config/brd4108a/sl_iostream_usart_bg96_config.h
+ condition: [brd4108a]
+ - override:
+ component: iostream_usart
+ file_id: iostream_usart_config
+ instance: bg96
+ path: public/mikroe/lte_iot2_bg96/config/brd2703a/sl_iostream_usart_bg96_config.h
+ condition: [brd2703a]
+provides:
+ - name: mikroe_lte_iot2
+ allow_multiple: false
+template_contribution:
+ - name: component_catalog
+ value: mikroe_lte_iot2
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: public/mikroe/lte_iot2_bg96/inc
+ file_list:
+ - path: mikroe_bg96.h
+ - path: at_parser_utility.h
+ - path: at_parser_platform.h
+ - path: at_parser_events.h
+ - path: at_parser_core.h
+source:
+ - path: public/mikroe/lte_iot2_bg96/src/mikroe_bg96.c
+ - path: public/mikroe/lte_iot2_bg96/src/at_parser_platform.c
+ - path: public/mikroe/lte_iot2_bg96/src/at_parser_events.c
+ - path: public/mikroe/lte_iot2_bg96/src/at_parser_core.c
\ No newline at end of file
diff --git a/driver/component/drivers/mikroe/microsd.slcc b/driver/component/drivers/mikroe/microsd.slcc
new file mode 100644
index 00000000..09085eca
--- /dev/null
+++ b/driver/component/drivers/mikroe/microsd.slcc
@@ -0,0 +1,29 @@
+id: mikroe_microsd
+package: third_party_hw_drivers
+label: microSD - microSD Click (Mikroe)
+description: >
+ Driver for the Mikroe microSD Click board.
+category: Storage
+quality: evaluation
+root_path: driver
+requires:
+ - name: status
+ - name: fatfs_sdc_spi_platform
+provides:
+ - name: fatfs_storage_device
+ - name: fatfs_storage_device_sdcard
+config_file:
+ - path: public/mikroe/microsd/config/mikroe_microsd_config.h
+ file_id: driver_config_microsd
+template_contribution:
+ - name: component_catalog
+ value: fatfs_storage_device_sdcard
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: public/mikroe/microsd/inc
+ file_list:
+ - path: sl_sdc_sd_card.h
+source:
+ - path: public/mikroe/microsd/src/sl_sdc_sd_card.c
diff --git a/driver/component/drivers/mikroe/nfc2_pn7120.slcc b/driver/component/drivers/mikroe/nfc2_pn7120.slcc
new file mode 100644
index 00000000..e7a9bc4e
--- /dev/null
+++ b/driver/component/drivers/mikroe/nfc2_pn7120.slcc
@@ -0,0 +1,49 @@
+id: mikroe_nfc2
+package: third_party_hw_drivers
+label: PN7150 - NFC 2 Click (Mikroe) - I2C
+description: >
+ Driver for the NFC 2 Click board, this board relies on the PN7150 IC using I2C interface.
+category: Wireless Connectivity
+quality: evaluation
+root_path: driver
+
+requires:
+ - name: status
+ - name: mikroe_peripheral_driver_digital_io
+ - name: mikroe_peripheral_driver_i2c
+
+provides:
+ - name: mikroe_nfc2
+ - name: nci_tml
+
+config_file:
+ - path: public/mikroe/nfc2_pn7150/config/brd4314a/mikroe_pn7150_config.h
+ file_id: driver_config_pn7150
+ condition: [brd4314a]
+ - path: public/mikroe/nfc2_pn7150/config/brd4108a/mikroe_pn7150_config.h
+ file_id: driver_config_pn7150
+ condition: [brd4108a]
+ - path: public/mikroe/nfc2_pn7150/config/brd2703a/mikroe_pn7150_config.h
+ file_id: driver_config_pn7150
+ condition: [brd2703a]
+
+template_contribution:
+ - name: component_catalog
+ value: mikroe_nfc2
+
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: thirdparty/mikrosdk_click_v2/clicks/nfc2/lib_nfc2/include
+ file_list:
+ - path: nfc2.h
+ - path: public/mikroe/nfc2_pn7150/inc
+ file_list:
+ - path: mikroe_pn7150.h
+ - path: nci_tml.h
+
+source:
+ - path: thirdparty/mikrosdk_click_v2/clicks/nfc2/lib_nfc2/src/nfc2.c
+ - path: public/mikroe/nfc2_pn7150/src/mikroe_pn7150.c
+ - path: public/mikroe/nfc2_pn7150/src/nci_tml.c
diff --git a/driver/component/drivers/mikroe/oledc_ssd1351.slcc b/driver/component/drivers/mikroe/oledc_ssd1351.slcc
new file mode 100644
index 00000000..4d887b5f
--- /dev/null
+++ b/driver/component/drivers/mikroe/oledc_ssd1351.slcc
@@ -0,0 +1,44 @@
+id: oledc_ssd1351
+package: third_party_hw_drivers
+label: SSD1351 - OLED C Click (Mikroe)
+description: >
+ Driver for the Mikroe OLED C Click display board.
+category: Display & LED
+quality: evaluation
+root_path: driver
+requires:
+ - name: status
+ - name: mikroe_peripheral_driver_spi
+provides:
+ - name: oled_display
+config_file:
+ - path: public/mikroe/oledc_ssd1351/config/brd2703a/mikroe_ssd1351_config.h
+ file_id: driver_config_oledc
+ condition: [brd2703a]
+ - path: public/mikroe/oledc_ssd1351/config/brd4108a/mikroe_ssd1351_config.h
+ file_id: driver_config_oledc
+ condition: [brd4108a]
+ - path: public/mikroe/oledc_ssd1351/config/brd4314a/mikroe_ssd1351_config.h
+ file_id: driver_config_oledc
+ condition: [brd4314a]
+template_contribution:
+ - name: component_catalog
+ value: oledc_ssd1351
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: thirdparty/mikrosdk_click_v2/clicks/oledc/lib/include
+ file_list:
+ - path: oledc.h
+ - path: oledc_font.h
+ - path: oledc_image.h
+ - path: public/mikroe/oledc_ssd1351/inc
+ file_list:
+ - path: mikroe_ssd1351.h
+ - path: mikroe_ssd1351_image.h
+ - path: oled_display.h
+source:
+ - path: thirdparty/mikrosdk_click_v2/clicks/oledc/lib/src/oledc.c
+ - path: public/mikroe/oledc_ssd1351/src/mikroe_ssd1351.c
+ - path: public/mikroe/oledc_ssd1351/src/oled_display.c
diff --git a/driver/component/drivers/mikroe/pressure_dps310_i2c.slcc b/driver/component/drivers/mikroe/pressure_dps310_i2c.slcc
new file mode 100644
index 00000000..cb0a047a
--- /dev/null
+++ b/driver/component/drivers/mikroe/pressure_dps310_i2c.slcc
@@ -0,0 +1,33 @@
+id: mikroe_pressure3_i2c
+package: third_party_hw_drivers
+label: DPS310 - Pressure 3 Click (Mikroe) - I2C
+description: >
+ Driver for the Pressure 3 Click CLICK board. Pressure 3 click is a mikroBUS add-on board that carries an Infineon DPS310 digital barometric pressure sensor on I2C communication.
+quality: evaluation
+ui_hints:
+ visibility: basic
+category: Sensors
+root_path: driver
+requires:
+ - name: mikroe_peripheral_driver_i2c
+ - name: mikroe_peripheral_driver_spi
+
+provides:
+ - name: mikroe_pressure3_i2c
+ allow_multiple: false
+template_contribution:
+ - name: component_catalog
+ value: mikroe_pressure3_i2c
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: thirdparty/mikrosdk_click_v2/clicks/pressure3/lib/include
+ file_list:
+ - path: pressure3.h
+ - path: public/mikroe/pressure3_dps310/inc
+ file_list:
+ - path: mikroe_dps310_i2c.h
+source:
+ - path: thirdparty/mikrosdk_click_v2/clicks/pressure3/lib/src/pressure3.c
+ - path: public/mikroe/pressure3_dps310/src/mikroe_dps310_i2c.c
\ No newline at end of file
diff --git a/driver/component/drivers/mikroe/pressure_dps310_spi.slcc b/driver/component/drivers/mikroe/pressure_dps310_spi.slcc
new file mode 100644
index 00000000..9e1bb490
--- /dev/null
+++ b/driver/component/drivers/mikroe/pressure_dps310_spi.slcc
@@ -0,0 +1,33 @@
+id: mikroe_pressure3_spi
+package: third_party_hw_drivers
+label: DPS310 - Pressure 3 Click (Mikroe) - SPI
+description: >
+ Driver for the Pressure 3 Click CLICK board. Pressure 3 click is a mikroBUS add-on board that carries an Infineon DPS310 digital barometric pressure sensor on SPI communication.
+quality: evaluation
+ui_hints:
+ visibility: basic
+category: Sensors
+root_path: driver
+requires:
+ - name: mikroe_peripheral_driver_i2c
+ - name: mikroe_peripheral_driver_spi
+
+provides:
+ - name: mikroe_pressure3_spi
+ allow_multiple: false
+template_contribution:
+ - name: component_catalog
+ value: mikroe_pressure3_spi
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: thirdparty/mikrosdk_click_v2/clicks/pressure3/lib/include
+ file_list:
+ - path: pressure3.h
+ - path: public/mikroe/pressure3_dps310/inc
+ file_list:
+ - path: mikroe_dps310_spi.h
+source:
+ - path: thirdparty/mikrosdk_click_v2/clicks/pressure3/lib/src/pressure3.c
+ - path: public/mikroe/pressure3_dps310/src/mikroe_dps310_spi.c
\ No newline at end of file
diff --git a/driver/component/drivers/mikroe/pwm_driver_si8711cc.slcc b/driver/component/drivers/mikroe/pwm_driver_si8711cc.slcc
new file mode 100644
index 00000000..252b9107
--- /dev/null
+++ b/driver/component/drivers/mikroe/pwm_driver_si8711cc.slcc
@@ -0,0 +1,31 @@
+id: pwm_driver_si8711cc
+package: third_party_hw_drivers
+label: Si8711CC - PWM Driver Click (Mikroe)
+description: >
+ Driver for the Mikroe PWM Driver Click board.
+category: Motor Control
+quality: evaluation
+ui_hints:
+ visibility: basic
+root_path: driver
+requires:
+ - name: mikroe_peripheral_driver_pwm
+provides:
+ - name: pwm_driver_si8711cc
+ allow_multiple: false
+template_contribution:
+ - name: component_catalog
+ value: pwm_driver_si8711cc
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: thirdparty/mikrosdk_click_v2/clicks/pwmdriver/lib/include
+ file_list:
+ - path: pwmdriver.h
+ - path: public/mikroe/pwm_driver_si8711cc/inc
+ file_list:
+ - path: mikroe_si8711cc.h
+source:
+ - path: thirdparty/mikrosdk_click_v2/clicks/pwmdriver/lib/src/pwmdriver.c
+ - path: public/mikroe/pwm_driver_si8711cc/src/mikroe_si8711cc.c
\ No newline at end of file
diff --git a/driver/component/drivers/mikroe/rf_meter_ad8318.slcc b/driver/component/drivers/mikroe/rf_meter_ad8318.slcc
new file mode 100644
index 00000000..9e8b60ef
--- /dev/null
+++ b/driver/component/drivers/mikroe/rf_meter_ad8318.slcc
@@ -0,0 +1,38 @@
+id: mirkoe_rf_meter
+package: third_party_hw_drivers
+label: AD8318 - RF Meter Click (Mikroe)
+description: >
+ Driver for the Mikroe RF Meter Click board.
+category: Sensors
+quality: evaluation
+
+ui_hints:
+ visibility: basic
+root_path: driver
+
+requires:
+ - name: mikroe_peripheral_driver_spi
+ - name: status
+
+provides:
+ - name: mirkoe_rf_meter
+ - allow_multiple: false
+
+template_contribution:
+ - name: component_catalog
+ - value: rf_meter_ad8318
+
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: thirdparty/mikrosdk_click_v2/clicks/rfmeter/lib_rfmeter/include
+ file_list:
+ - path: rfmeter.h
+ - path: public/mikroe/rf_meter_ad8318/inc
+ file_list:
+ - path: mikroe_ad8318.h
+
+source:
+ - path: thirdparty/mikrosdk_click_v2/clicks/rfmeter/lib_rfmeter/src/rfmeter.c
+ - path: public/mikroe/rf_meter_ad8318/src/mikroe_ad8318.c
diff --git a/driver/component/drivers/silabs/fatfs_sdc_spi_platform.slcc b/driver/component/drivers/silabs/fatfs_sdc_spi_platform.slcc
new file mode 100644
index 00000000..05cae643
--- /dev/null
+++ b/driver/component/drivers/silabs/fatfs_sdc_spi_platform.slcc
@@ -0,0 +1,24 @@
+id: fatfs_sdc_spi_platform
+package: third_party_hw_drivers
+label: Storage Device Controls Platform - SPI
+description: >
+ Storage device controls platform interfaces for SPI interfaced FatFS storage devices.
+category: Services/FatFS - Generic FAT Filesystem
+quality: evaluation
+ui_hints:
+ visibility: never
+root_path: driver
+requires:
+ - name: status
+ - name: mikroe_peripheral_driver_spi
+provides:
+ - name: fatfs_sdc_spi_platform
+template_contribution:
+ - name: component_catalog
+ value: fatfs_sdc_spi_platform
+include:
+ - path: public/silabs/fatfs_sdc_spi_platform/inc
+ file_list:
+ - path: sl_sdc_platform_spi.h
+source:
+ - path: public/silabs/fatfs_sdc_spi_platform/src/sl_sdc_platform_spi.c
\ No newline at end of file
diff --git a/driver/component/drivers/silabs/mikroe_nfctag2_nt3h2111.slcc b/driver/component/drivers/silabs/mikroe_nfctag2_nt3h2111.slcc
new file mode 100644
index 00000000..85971fa0
--- /dev/null
+++ b/driver/component/drivers/silabs/mikroe_nfctag2_nt3h2111.slcc
@@ -0,0 +1,49 @@
+id: mikroe_nfctag2
+package: third_party_hw_drivers
+label: NT3H2111 - NFC Tag 2 Click (Mikroe) - I2C
+description: >
+ Driver for the NFC Tag 2 Click board, this board relies on the NT3H2111 IC using I2C interface.
+category: Wireless Connectivity
+quality: evaluation
+ui_hints:
+ visibility: basic
+root_path: driver
+
+requires:
+ - name: status
+ - name: i2cspm
+ - name: sleeptimer
+recommends:
+ - id: i2cspm
+ instance: [mikroe]
+
+config_file:
+ - path: public/silabs/nfctag2_nt3h2111/config/brd4314a/mikroe_nt3h2111_config.h
+ file_id: driver_config_nt3h2111
+ condition: [brd4314a]
+ - path: public/silabs/nfctag2_nt3h2111/config/brd4108a/mikroe_nt3h2111_config.h
+ file_id: driver_config_nt3h2111
+ condition: [brd4108a]
+ - path: public/silabs/nfctag2_nt3h2111/config/brd2703a/mikroe_nt3h2111_config.h
+ file_id: driver_config_nt3h2111
+ condition: [brd2703a]
+ - path: public/silabs/nfctag2_nt3h2111/config/other/mikroe_nt3h2111_config.h
+ file_id: driver_config_bma400_i2c
+ unless: [brd4314a, brd4108a, brd2703a]
+
+provides:
+ - name: mikroe_nfctag2
+
+template_contribution:
+ - name: component_catalog
+ value: mikroe_nfctag2
+
+include:
+ - path: public/silabs/nfctag2_nt3h2111/inc
+ file_list:
+ - path: mikroe_nt3h2111_i2c.h
+ - path: mikroe_nt3h2111.h
+
+source:
+ - path: public/silabs/nfctag2_nt3h2111/src/mikroe_nt3h2111_i2c.c
+ - path: public/silabs/nfctag2_nt3h2111/src/mikroe_nt3h2111.c
\ No newline at end of file
diff --git a/driver/component/drivers/silabs/mikroe_stepper_a3967.slcc b/driver/component/drivers/silabs/mikroe_stepper_a3967.slcc
new file mode 100644
index 00000000..71cd5d47
--- /dev/null
+++ b/driver/component/drivers/silabs/mikroe_stepper_a3967.slcc
@@ -0,0 +1,38 @@
+id: mikroe_stepper_a3967
+package: third_party_hw_drivers
+label: A3967 - Stepper Click (Mikroe)
+description: >
+ Driver for the Mikroe Stepper Click board.
+category: Motor Control
+quality: evaluation
+ui_hints:
+ visibility: basic
+root_path: driver
+requires:
+ - name: status
+ - name: sleeptimer
+provides:
+ - name: mikroe_stepper_a3967
+ allow_multiple: false
+config_file:
+ - path: public/silabs/stepper_a3967/config/brd4314a/mikroe_a3967_config.h
+ file_id: mikroe_a3967_config
+ condition: [brd4314a]
+ - path: public/silabs/stepper_a3967/config/brd2703a/mikroe_a3967_config.h
+ file_id: mikroe_a3967_config
+ condition: [brd2703a]
+ - path: public/silabs/stepper_a3967/config/brd4108a/mikroe_a3967_config.h
+ file_id: mikroe_a3967_config
+ condition: [brd4108a]
+template_contribution:
+ - name: component_catalog
+ value: mikroe_stepper_a3967
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: public/silabs/stepper_a3967/inc
+ file_list:
+ - path: mikroe_a3967.h
+source:
+ - path: public/silabs/stepper_a3967/src/mikroe_a3967.c
\ No newline at end of file
diff --git a/driver/component/drivers/silabs/pir_ira_s210st01.slcc b/driver/component/drivers/silabs/pir_ira_s210st01.slcc
new file mode 100644
index 00000000..71524420
--- /dev/null
+++ b/driver/component/drivers/silabs/pir_ira_s210st01.slcc
@@ -0,0 +1,41 @@
+id: silabs_pir_ira_s210st01
+package: third_party_hw_drivers
+label: IRA-S210ST01 - PIR Sensor (Silabs)
+description: >
+ Driver for the PIR sensor driver using the PIR sensor on the occupancy sensor EXP board.
+category: Sensors
+quality: evaluation
+ui_hints:
+ visibility: basic
+root_path: driver
+requires:
+ - name: emlib_cryotimer
+ condition: [device_series_1]
+ - name: emlib_opamp
+ condition: [device_series_1]
+ - name: emlib_vdac
+ condition: [device_series_1]
+ - name: emlib_letimer
+ - name: emlib_prs
+ - name: emlib_adc
+ condition: [device_series_1]
+ - name: emlib_iadc
+ condition: [device_series_2]
+config_file:
+ - path: public/silabs/pir_ira_s210st01/config/pir_ira_s210st01_config.h
+ file_id: driver_config_pir_ira_s210st01
+template_contribution:
+ - name: component_catalog
+ value: silabs_pir_ira_s210st01
+include:
+ - path: inc
+ file_list:
+ - path: third_party_hw_drivers_helpers.h
+ - path: public/silabs/pir_ira_s210st01/inc
+ file_list:
+ - path: pir_ira_s210st01.h
+source:
+ - path: public/silabs/pir_ira_s210st01/src/pir_ira_s210st01_s1.c
+ condition: [device_series_1]
+ - path: public/silabs/pir_ira_s210st01/src/pir_ira_s210st01_s2.c
+ condition: [device_series_2]
diff --git a/driver/component/drivers/silabs/silabs_ir_generate.slcc b/driver/component/drivers/silabs/silabs_ir_generate.slcc
new file mode 100644
index 00000000..29e4f473
--- /dev/null
+++ b/driver/component/drivers/silabs/silabs_ir_generate.slcc
@@ -0,0 +1,26 @@
+id: silabs_ir_generate
+package: third_party_hw_drivers
+label: IR Generator (Silabs)
+description: >
+ Driver for the IR generator driver using WSTK kit.
+category: Miscellaneous
+quality: evaluation
+root_path: driver
+requires:
+ - name: status
+ - name: emlib_prs
+ - name: emlib_timer
+config_file:
+ - path: public/silabs/ir_generate/config/ir_generate_config.h
+ file_id: ir_generate_drv_config
+provides:
+ - name: silabs_ir_generate
+template_contribution:
+ - name: component_catalog
+ value: silabs_ir_generate
+include:
+ - path: public/silabs/ir_generate/inc
+ file_list:
+ - path: ir_generate.h
+source:
+ - path: public/silabs/ir_generate/src/ir_generate.c
diff --git a/driver/component/drivers/silabs/silabs_triac.slcc b/driver/component/drivers/silabs/silabs_triac.slcc
new file mode 100644
index 00000000..301d2889
--- /dev/null
+++ b/driver/component/drivers/silabs/silabs_triac.slcc
@@ -0,0 +1,27 @@
+id: silabs_triac
+package: third_party_hw_drivers
+label: Triac Driver (Silabs)
+description: >
+ Driver for for Series 1 EFM32 and EFR32 devices that uses an appropriate voltage level representation of the AC line voltage in order to fire a timed pulse to drive the gate on a triac.
+category: Miscellaneous
+quality: evaluation
+root_path: driver
+requires:
+ - name: status
+ - name: emlib_acmp
+ - name: emlib_timer
+ - name: emlib_prs
+config_file:
+ - path: public/silabs/triac/config/triacdrv_config.h
+ file_id: triacdrv_config
+provides:
+ - name: silabs_triac
+template_contribution:
+ - name: component_catalog
+ value: silabs_triac
+include:
+ - path: public/silabs/triac/inc
+ file_list:
+ - path: triacdrv.h
+source:
+ - path: public/silabs/triac/src/triacdrv.c
diff --git a/driver/component/drivers/silabs/sparkfun_ir_array_amg88xx.slcc b/driver/component/drivers/silabs/sparkfun_ir_array_amg88xx.slcc
new file mode 100644
index 00000000..1808c334
--- /dev/null
+++ b/driver/component/drivers/silabs/sparkfun_ir_array_amg88xx.slcc
@@ -0,0 +1,34 @@
+id: sparkfun_ir_array_amg88xx
+package: third_party_hw_drivers
+label: AMG88XX - Grid-EYE Infrared Array Breakout (Sparkfun)
+description: >
+ Driver for the Sparkfun Grid-EYE Infrared Array Breakout - AMG8833 (Qwiic) board.
+category: Sensors
+quality: evaluation
+root_path: driver
+requires:
+ - name: status
+ - name: sleeptimer
+ - name: i2cspm
+recommends:
+ - id: i2cspm
+ instance: [qwiic]
+config_file:
+ - path: "public/silabs/ir_array_amg88xx/config/brd2601b/sl_i2cspm_qwiic_config.h"
+ condition: [brd2601b]
+ override:
+ component: i2cspm
+ file_id: i2cspm_config
+ instance: qwiic
+
+provides:
+ - name: sparkfun_ir_array_amg88xx
+template_contribution:
+ - name: component_catalog
+ value: sparkfun_ir_array_amg88xx
+include:
+ - path: public/silabs/ir_array_amg88xx/inc
+ file_list:
+ - path: ir_array_amg88xx.h
+source:
+ - path: public/silabs/ir_array_amg88xx/src/ir_array_amg88xx.c
\ No newline at end of file
diff --git a/driver/component/services/fatfs.slcc b/driver/component/services/fatfs.slcc
new file mode 100644
index 00000000..2bda1cdb
--- /dev/null
+++ b/driver/component/services/fatfs.slcc
@@ -0,0 +1,34 @@
+id: services_fatfs
+package: third_party_hw_drivers
+label: FatFS - Generic FAT Filesystem
+description: >
+ FatFs is a generic FAT/exFAT filesystem module for small embedded systems.
+category: Services
+quality: evaluation
+root_path: driver
+requires:
+- name: fatfs_storage_device
+- name: sleeptimer
+- name: component_catalog
+provides:
+- name: services_fatfs
+ allow_multiple: false
+config_file:
+- path: public/silabs/services_fatfs/config/ffconf.h
+ file_id: fatfs_config
+- override:
+ component: sleeptimer
+ file_id: sleeptimer_config
+ path: public/silabs/services_fatfs/config/sl_sleeptimer_config.h
+include:
+- path: public/silabs/services_fatfs/inc
+ file_list:
+ - path: diskio.h
+- path: thirdparty/fatfs
+ file_list:
+ - path: ff.h
+source:
+- path: public/silabs/services_fatfs/src/sl_sdc_media.c
+- path: thirdparty/fatfs/ff.c
+- path: thirdparty/fatfs/ffsystem.c
+- path: thirdparty/fatfs/ffunicode.c
\ No newline at end of file
diff --git a/driver/component/services/nfc_common.slcc b/driver/component/services/nfc_common.slcc
new file mode 100644
index 00000000..b54095cb
--- /dev/null
+++ b/driver/component/services/nfc_common.slcc
@@ -0,0 +1,26 @@
+id: services_nfc_common
+package: third_party_hw_drivers
+label: NFC - Common
+description: >
+ Contains files commonly used across different NFC library components.
+category: Services|NFC
+quality: evaluation
+root_path: driver
+
+provides:
+ - name: nfc_common
+ allow_multiple: false
+
+template_contribution:
+ - name: component_catalog
+ value: nfc_common
+
+include:
+ - path: public/silabs/services_nfc/common/inc
+ file_list:
+ - path: nfc_serial.h
+ - path: nfc_tlv.h
+
+source:
+ - path: public/silabs/services_nfc/common/src/nfc_serial.c
+ - path: public/silabs/services_nfc/common/src/nfc_tlv.c
\ No newline at end of file
diff --git a/driver/component/services/nfc_nci.slcc b/driver/component/services/nfc_nci.slcc
new file mode 100644
index 00000000..3727934f
--- /dev/null
+++ b/driver/component/services/nfc_nci.slcc
@@ -0,0 +1,38 @@
+id: services_nfc_nci
+package: third_party_hw_drivers
+label: NFC - NCI
+description: >
+ Events based NCI.
+category: Services|NFC
+quality: evaluation
+root_path: driver
+
+requires:
+ - name: nfc_common
+ - name: nci_tml
+
+provides:
+ - name: nfc_nci
+ allow_multiple: false
+
+template_contribution:
+ - name: component_catalog
+ value: nfc_nci
+
+config_file:
+ - path: public/silabs/services_nfc/nci/config/nci_config.h
+ file_id: nfc_nci_config
+
+include:
+ - path: public/silabs/services_nfc/nci/inc
+ file_list:
+ - path: nci.h
+ - path: nci_nxp_ext.h
+ - path: nci_evt.h
+ - path: nci_err.h
+ - path: nci_dbg.h
+
+source:
+ - path: public/silabs/services_nfc/nci/src/nci_dbg.c
+ - path: public/silabs/services_nfc/nci/src/nci_nxp_ext.c
+ - path: public/silabs/services_nfc/nci/src/nci.c
\ No newline at end of file
diff --git a/driver/component/services/nfc_ndef.slcc b/driver/component/services/nfc_ndef.slcc
new file mode 100644
index 00000000..e68c400f
--- /dev/null
+++ b/driver/component/services/nfc_ndef.slcc
@@ -0,0 +1,26 @@
+id: services_nfc_ndef
+package: third_party_hw_drivers
+label: NFC - NDEF
+description: >
+ NFC data exchange format (NDEF).
+category: Services|NFC
+quality: evaluation
+root_path: driver
+
+provides:
+ - name: nfc_ndef
+ allow_multiple: false
+
+template_contribution:
+ - name: component_catalog
+ value: nfc_ndef
+
+include:
+ - path: public/silabs/services_nfc/ndef/inc
+ file_list:
+ - path: ndef_message.h
+ - path: ndef_record.h
+
+source:
+ - path: public/silabs/services_nfc/ndef/src/ndef_message.c
+ - path: public/silabs/services_nfc/ndef/src/ndef_record.c
\ No newline at end of file
diff --git a/driver/component/services/nfc_tag.slcc b/driver/component/services/nfc_tag.slcc
new file mode 100644
index 00000000..032f881b
--- /dev/null
+++ b/driver/component/services/nfc_tag.slcc
@@ -0,0 +1,23 @@
+id: services_nfc_tag
+package: third_party_hw_drivers
+label: NFC - Tag
+description: >
+ NFC forum tags related files.
+category: Services|NFC
+quality: evaluation
+root_path: driver
+
+provides:
+ - name: nfc_tag
+ allow_multiple: false
+
+template_contribution:
+ - name: component_catalog
+ value: nfc_tag
+
+include:
+ - path: public/silabs/services_nfc/tag/inc
+ file_list:
+ - path: nfc_t2t.h
+ - path: nfc_t4t.h
+ - path: nfc_tag_dbg.h
\ No newline at end of file
diff --git a/driver/peripheral_drivers/mikroe/inc/hal_target.h b/driver/peripheral_drivers/mikroe/inc/hal_target.h
index 68da37df..33e57b4d 100644
--- a/driver/peripheral_drivers/mikroe/inc/hal_target.h
+++ b/driver/peripheral_drivers/mikroe/inc/hal_target.h
@@ -63,6 +63,7 @@ extern void sl_sleeptimer_delay_millisecond(uint16_t time_ms);
#define Delay_10us() sl_udelay_wait(10)
#define Delay_22us() sl_udelay_wait(22)
#define Delay_50us() sl_udelay_wait(50)
+#define Delay_80us() sl_udelay_wait(80)
#define Delay_100us() sl_udelay_wait(100)
#define Delay_500us() sl_udelay_wait(500)
@@ -75,7 +76,6 @@ extern void sl_sleeptimer_delay_millisecond(uint16_t time_ms);
// Delay functions in seconds
#define Delay_1sec() sl_sleeptimer_delay_millisecond(1000)
-
#ifdef __cplusplus
}
#endif
diff --git a/driver/public/mikroe/e_paper_154_inch/config/brd2703a/mikroe_e_paper_154_inch_config.h b/driver/public/mikroe/e_paper_154_inch/config/brd2703a/mikroe_e_paper_154_inch_config.h
new file mode 100644
index 00000000..51beb6c2
--- /dev/null
+++ b/driver/public/mikroe/e_paper_154_inch/config/brd2703a/mikroe_e_paper_154_inch_config.h
@@ -0,0 +1,75 @@
+/***************************************************************************//**
+ * @file mikroe_e_paper_config.h
+ * @brief Mikroe E-Paper Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_E_PAPER_154_INCH_CONFIG_H_
+#define MIKROE_E_PAPER_154_INCH_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MIKROE_E_PAPER_WIDTH 200
+#define MIKROE_E_PAPER_HEIGHT 200
+
+// <<< sl:start pin_tool >>>
+
+// E_PAPER_154_INCH_DC
+// $[GPIO_E_PAPER_154_INCH_DC]
+#define E_PAPER_DC_PORT gpioPortA
+#define E_PAPER_DC_PIN 0
+// [GPIO_SSD1306_DC]$
+
+// E_PAPER_154_INCH_RST
+// $[GPIO_E_PAPER_154_INCH_RST]
+#define E_PAPER_RST_PORT gpioPortC
+#define E_PAPER_RST_PIN 8
+// [GPIO_E_PAPER_RST]$
+
+// E_PAPER_BSY
+// $[GPIO_E_PAPER_BSY]
+#define E_PAPER_BSY_PORT gpioPortB
+#define E_PAPER_BSY_PIN 1
+// [GPIO_E_PAPER_RST]$
+
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_E_PAPER_154_INCH_CONFIG_H_ */
diff --git a/driver/public/mikroe/e_paper_154_inch/config/brd4108a/mikroe_e_paper_154_inch_config.h b/driver/public/mikroe/e_paper_154_inch/config/brd4108a/mikroe_e_paper_154_inch_config.h
new file mode 100644
index 00000000..8424182d
--- /dev/null
+++ b/driver/public/mikroe/e_paper_154_inch/config/brd4108a/mikroe_e_paper_154_inch_config.h
@@ -0,0 +1,75 @@
+/***************************************************************************//**
+ * @file mikroe_e_paper_config.h
+ * @brief Mikroe E-Paper Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_E_PAPER_154_INCH_CONFIG_H_
+#define MIKROE_E_PAPER_154_INCH_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MIKROE_E_PAPER_WIDTH 200
+#define MIKROE_E_PAPER_HEIGHT 200
+
+// <<< sl:start pin_tool >>>
+
+// E_PAPER_154_INCH_DC
+// $[GPIO_E_PAPER_154_INCH_DC]
+#define E_PAPER_DC_PORT gpioPortB
+#define E_PAPER_DC_PIN 4
+// [GPIO_SSD1306_DC]$
+
+// E_PAPER_154_INCH_RST
+// $[GPIO_E_PAPER_154_INCH_RST]
+#define E_PAPER_RST_PORT gpioPortC
+#define E_PAPER_RST_PIN 6
+// [GPIO_E_PAPER_RST]$
+
+// E_PAPER_BSY
+// $[GPIO_E_PAPER_BSY]
+#define E_PAPER_BSY_PORT gpioPortB
+#define E_PAPER_BSY_PIN 3
+// [GPIO_E_PAPER_RST]$
+
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_E_PAPER_154_INCH_CONFIG_H_ */
diff --git a/driver/public/mikroe/e_paper_154_inch/config/brd4314a/mikroe_e_paper_154_inch_config.h b/driver/public/mikroe/e_paper_154_inch/config/brd4314a/mikroe_e_paper_154_inch_config.h
new file mode 100644
index 00000000..8424182d
--- /dev/null
+++ b/driver/public/mikroe/e_paper_154_inch/config/brd4314a/mikroe_e_paper_154_inch_config.h
@@ -0,0 +1,75 @@
+/***************************************************************************//**
+ * @file mikroe_e_paper_config.h
+ * @brief Mikroe E-Paper Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_E_PAPER_154_INCH_CONFIG_H_
+#define MIKROE_E_PAPER_154_INCH_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MIKROE_E_PAPER_WIDTH 200
+#define MIKROE_E_PAPER_HEIGHT 200
+
+// <<< sl:start pin_tool >>>
+
+// E_PAPER_154_INCH_DC
+// $[GPIO_E_PAPER_154_INCH_DC]
+#define E_PAPER_DC_PORT gpioPortB
+#define E_PAPER_DC_PIN 4
+// [GPIO_SSD1306_DC]$
+
+// E_PAPER_154_INCH_RST
+// $[GPIO_E_PAPER_154_INCH_RST]
+#define E_PAPER_RST_PORT gpioPortC
+#define E_PAPER_RST_PIN 6
+// [GPIO_E_PAPER_RST]$
+
+// E_PAPER_BSY
+// $[GPIO_E_PAPER_BSY]
+#define E_PAPER_BSY_PORT gpioPortB
+#define E_PAPER_BSY_PIN 3
+// [GPIO_E_PAPER_RST]$
+
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_E_PAPER_154_INCH_CONFIG_H_ */
diff --git a/driver/public/mikroe/e_paper_154_inch/inc/mikroe_e_paper_154_inch.h b/driver/public/mikroe/e_paper_154_inch/inc/mikroe_e_paper_154_inch.h
new file mode 100644
index 00000000..ef9a8edf
--- /dev/null
+++ b/driver/public/mikroe/e_paper_154_inch/inc/mikroe_e_paper_154_inch.h
@@ -0,0 +1,297 @@
+/***************************************************************************//**
+ * @file mikroe_e_paper.c
+ * @brief SCL Mikroe E-Paper Header File
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_E_PAPER_154_INCH_H_
+#define MIKROE_E_PAPER_154_INCH_H_
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "eink_154inch.h"
+#include "spidrv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// -----------------------------------------------------------------------------
+// Macros
+// -----------------------------------------------------------------------------
+
+/* E-Paper Screen color */
+#define E_PAPER_SCREEN_COLOR_WHITE 0xFF
+#define E_PAPER_SCREEN_COLOR_BLACK 0x00
+
+/* E-Paper Display Command */
+#define E_PAPER_CMD_DRIVER_OUTPUT_CONTROL 0x01
+#define E_PAPER_CMD_BOOSTER_SOFT_START_CONTROL 0x0C
+#define E_PAPER_CMD_GATE_SCAN_START_POSITION 0x0F
+#define E_PAPER_CMD_DEEP_SLEEP_MODE 0x10
+#define E_PAPER_CMD_DATA_ENTRY_MODE_SETTING 0x11
+#define E_PAPER_CMD_SW_RESET 0x12
+#define E_PAPER_CMD_TEMPERATURE_SENSOR_CONTROL 0x1A
+#define E_PAPER_CMD_MASTER_ACTIVATION 0x20
+#define E_PAPER_CMD_DISPLAY_UPDATE_CONTROL_1 0x21
+#define E_PAPER_CMD_DISPLAY_UPDATE_CONTROL_2 0x22
+#define E_PAPER_CMD_WRITE_RAM 0x24
+#define E_PAPER_CMD_WRITE_VCOM_REGISTER 0x2C
+#define E_PAPER_CMD_WRITE_LUT_REGISTER 0x32
+#define E_PAPER_CMD_SET_DUMMY_LINE_PERIOD 0x3A
+#define E_PAPER_CMD_SET_GATE_TIME 0x3B
+#define E_PAPER_CMD_BORDER_WAVEFORM_CONTROL 0x3C
+#define E_PAPER_CMD_SET_RAM_X_ADDRESS_START_END_POSITION 0x44
+#define E_PAPER_CMD_SET_RAM_Y_ADDRESS_START_END_POSITION 0x45
+#define E_PAPER_CMD_SET_RAM_X_ADDRESS_COUNTER 0x4E
+#define E_PAPER_CMD_SET_RAM_Y_ADDRESS_COUNTER 0x4F
+#define E_PAPER_CMD_TERMINATE_FRAME_READ_WRITE 0xFF
+
+// -----------------------------------------------------------------------------
+// Public Functions
+// -----------------------------------------------------------------------------
+
+/***************************************************************************//**
+ * @brief
+ * Initialization function.
+ *
+ * @param[in] spi_instance
+ * SPI instance
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_init(SPIDRV_Handle_t spi_instance);
+
+/***************************************************************************//**
+ * @brief
+ * Generic transfer function.
+ *
+ * @param[in] wr_buf
+ * Write data buffer
+ * @param[in] wr_len
+ * Number of byte in write data buffer
+ * @param[in] rd_buf
+ * Read data buffer
+ * @param[in] rd_len
+ * Number of byte in read data buffer
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_generic_transfer(uint8_t *wr_buf,
+ uint16_t wr_len,
+ uint8_t *rd_buf,
+ uint16_t rd_len);
+
+/***************************************************************************//**
+ * @brief
+ * Sending command function.
+ *
+ * @param[in] command
+ * The command to be sent
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_send_command(uint8_t command);
+
+/***************************************************************************//**
+ * @brief
+ * Sending data function.
+ *
+ * @param[in] data
+ * The data to be sent
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_send_data(uint8_t data);
+
+/***************************************************************************//**
+ * @brief
+ * Reset chip function.
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_reset(void);
+
+/***************************************************************************//**
+ * @brief
+ * Sleep mode function.
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_sleep_mode(void);
+
+/***************************************************************************//**
+ * @brief
+ * Configuration display function.
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_start_config(void);
+
+/***************************************************************************//**
+ * @brief
+ * Set LUT table function.
+ *
+ * @param[in] lut
+ * Lut table
+ * @param[in] n_bytes
+ * Number of bytes in Lut table
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_set_lut(const uint8_t *lut,
+ uint8_t n_bytes);
+
+/***************************************************************************//**
+ * @brief
+ * Setting pointers in memory.
+ *
+ * @param[in] x
+ * x position
+ * @param[in] y
+ * y position
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_set_memory_pointer(uint8_t x, uint8_t y);
+
+/***************************************************************************//**
+ * @brief
+ * Setting area in memory.
+ *
+ * @param[in] xy
+ * Struct object
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_set_memory_area(eink_154_xy_t *xy);
+
+/***************************************************************************//**
+ * @brief
+ * Update display function.
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_update_display();
+
+/***************************************************************************//**
+ * @brief
+ * Function that fills the screen.
+ *
+ * @param[in] lut
+ * Lut table
+ * @param[in] color
+ * The color to which the screen will be colored.
+ * Options :
+ * E_PAPER_SCREEN_COLOR_WHITE
+ * E_PAPER_SCREEN_COLOR_BLACK
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_fill_screen(uint8_t color);
+
+/***************************************************************************//**
+ * @brief
+ * Displays image function.
+ *
+ * @param[in] image_buffer
+ * Buffer containing the image.
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_display_image(const uint8_t *image_buffer);
+
+/***************************************************************************//**
+ * @brief
+ * Displays image function.
+ *
+ * @param[in] text
+ * Text buffer.
+ * @param[in] text_set
+ * Struct object.
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_text(char *text,
+ eink_154_text_set_t *text_set);
+
+/***************************************************************************//**
+ * @brief
+ * Displays image function.
+ *
+ * @param[in] cfg_font
+ * Struct object.
+ *
+ * @return
+ * SL_STATUS_OK if Succeed .
+ * SL_STATUS_FAIL if failed.
+ ******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_set_font(eink_154inch_font_t *cfg_font);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_E_PAPER_H_ */
diff --git a/driver/public/mikroe/e_paper_154_inch/inc/oled_display.h b/driver/public/mikroe/e_paper_154_inch/inc/oled_display.h
new file mode 100644
index 00000000..95c98fef
--- /dev/null
+++ b/driver/public/mikroe/e_paper_154_inch/inc/oled_display.h
@@ -0,0 +1,89 @@
+/***************************************************************************//**
+ * @file oled_display.h
+ * @brief OLED Driver API interface
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#ifndef OLED_DISPLAY_H
+#define OLED_DISPLAY_H
+
+#include
+#include "sl_status.h"
+
+#include "mikroe_e_paper_154_inch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct oled_display_driver_api {
+ sl_status_t (*init)(void);
+ sl_status_t (*draw_pixel)(int16_t x, int16_t y, uint16_t color);
+ uint16_t (*get_raw_pixel)(int16_t x, int16_t y);
+ sl_status_t (*fill_screen)(uint16_t color);
+ sl_status_t (*update_display)(void);
+ sl_status_t (*set_invert_color)(void);
+ sl_status_t (*set_normal_color)(void);
+ sl_status_t (*set_contrast)(uint8_t);
+ sl_status_t (*scroll_right)(uint8_t, uint8_t);
+ sl_status_t (*scroll_left)(uint8_t, uint8_t);
+ sl_status_t (*scroll_diag_right)(uint8_t, uint8_t);
+ sl_status_t (*scroll_diag_left)(uint8_t, uint8_t);
+ sl_status_t (*stop_scroll)(void);
+ sl_status_t (*enable_display)(bool);
+} oled_display_driver_api_t;
+
+/**
+ * General memory LCD data structure.
+ */
+typedef struct oled_display {
+ unsigned short width; ///< Display pixel width
+ unsigned short height; ///< Display pixel height
+ const oled_display_driver_api_t *driver;
+} oled_display_t;
+
+/**************************************************************************//**
+ * @brief
+ * Initialization function for the LS013B7DH03 device driver.
+ *
+ * @return
+ * If all operations completed sucessfully SL_STATUS_OK is returned. On
+ * failure a different status code is returned specifying the error.
+ *****************************************************************************/
+sl_status_t oled_display_init(void);
+
+const oled_display_t *oled_display_get(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver/public/mikroe/e_paper_154_inch/src/mikroe_e_paper_154_inch.c b/driver/public/mikroe/e_paper_154_inch/src/mikroe_e_paper_154_inch.c
new file mode 100644
index 00000000..e5e1bc79
--- /dev/null
+++ b/driver/public/mikroe/e_paper_154_inch/src/mikroe_e_paper_154_inch.c
@@ -0,0 +1,216 @@
+/***************************************************************************//**
+ * @file mikroe_e_paper.c
+ * @brief SCL Mikroe E-Paper Header File
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "mikroe_e_paper_154_inch.h"
+#include "third_party_hw_drivers_helpers.h"
+#include "mikroe_e_paper_154_inch_config.h"
+
+// -----------------------------------------------------------------------------
+// Local Variables
+// -----------------------------------------------------------------------------
+
+static eink_154inch_t eink_ctx;
+static eink_154inch_cfg_t eink_cfg;
+static bool initialized = false;
+
+// -----------------------------------------------------------------------------
+// Public Functions
+// -----------------------------------------------------------------------------
+
+/**************************************************************************//**
+* E-Paper initialization.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_init(SPIDRV_Handle_t spi_instance)
+{
+ THIRD_PARTY_HW_DRV_RETCODE_INIT();
+
+ if (spi_instance == NULL) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ if (initialized) {
+ return SL_STATUS_ALREADY_INITIALIZED;
+ }
+
+ eink_ctx.spi.handle = spi_instance;
+ eink_154inch_cfg_setup(&eink_cfg);
+
+ eink_cfg.dc = hal_gpio_pin_name(E_PAPER_DC_PORT, E_PAPER_DC_PIN);
+ eink_cfg.bsy = hal_gpio_pin_name(E_PAPER_BSY_PORT, E_PAPER_BSY_PIN);
+ eink_cfg.rst = hal_gpio_pin_name(E_PAPER_RST_PORT, E_PAPER_RST_PIN);
+
+ THIRD_PARTY_HW_DRV_RETCODE_TEST(eink_154inch_init(&eink_ctx, &eink_cfg));
+ initialized = true;
+
+ return THIRD_PARTY_HW_DRV_RETCODE_VALUE;
+}
+
+/**************************************************************************//**
+* E-Paper generic transfer.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_generic_transfer(uint8_t *wr_buf,
+ uint16_t wr_len,
+ uint8_t *rd_buf,
+ uint16_t rd_len)
+{
+ eink_154inch_generic_transfer(&eink_ctx, wr_buf, wr_len, rd_buf, rd_len);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper send command.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_send_command(uint8_t command)
+{
+ eink154_send_command(&eink_ctx, command);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper send data.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_send_data(uint8_t data)
+{
+ eink154_send_data(&eink_ctx, data);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper reset.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_reset(void)
+{
+ eink154_reset(&eink_ctx);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper sleep mode.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_sleep_mode(void)
+{
+ eink154_sleep_mode(&eink_ctx);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper start config.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_start_config(void)
+{
+ eink154_start_config(&eink_ctx);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper set lut.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_set_lut(const uint8_t *lut, uint8_t n_bytes)
+{
+ eink154_set_lut(&eink_ctx, lut, n_bytes);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper set memory pointer.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_set_memory_pointer(uint8_t x, uint8_t y)
+{
+ eink154_set_memory_pointer(&eink_ctx, x, y);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper set memory area.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_set_memory_area(eink_154_xy_t *xy)
+{
+ eink154_set_memory_area(&eink_ctx, xy);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper update display.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_update_display(void)
+{
+ eink154_update_display(&eink_ctx);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper fill screen.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_fill_screen(uint8_t color)
+{
+ eink154_fill_screen(&eink_ctx, color);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper display image.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_display_image(const uint8_t *image_buffer)
+{
+ eink154_display_image(&eink_ctx, image_buffer);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper text.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_text(char *text,
+ eink_154_text_set_t *text_set)
+{
+ eink154_text(&eink_ctx, text, text_set);
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+* E-Paper set font.
+******************************************************************************/
+sl_status_t mikroe_e_paper_154_inch_set_font(eink_154inch_font_t *cfg_font)
+{
+ eink154_set_font(&eink_ctx, cfg_font);
+ return SL_STATUS_OK;
+}
diff --git a/driver/public/mikroe/e_paper_154_inch/src/oled_display.c b/driver/public/mikroe/e_paper_154_inch/src/oled_display.c
new file mode 100644
index 00000000..18ed6900
--- /dev/null
+++ b/driver/public/mikroe/e_paper_154_inch/src/oled_display.c
@@ -0,0 +1,140 @@
+/***************************************************************************//**
+ * @file oled_display.c
+ * @brief OLED Driver API interface
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#include
+#include "mikroe_e_paper_154_inch_config.h"
+#include "mikroe_e_paper_154_inch.h"
+#include "oled_display.h"
+
+/* This oled_frame_buffer is large enough to store one full frame. */
+static uint8_t oled_frame_buffer[(MIKROE_E_PAPER_WIDTH
+ * MIKROE_E_PAPER_HEIGHT) / 8];
+
+static sl_status_t driver_init(void);
+static sl_status_t draw_pixel(int16_t x, int16_t y, uint16_t color);
+static sl_status_t fill_screen(uint16_t color);
+static sl_status_t update_display(void);
+
+static oled_display_t oled_display_instance;
+static const oled_display_driver_api_t sl_memlcd_driver_api =
+{
+ .init = driver_init,
+ .draw_pixel = draw_pixel,
+ .get_raw_pixel = NULL,
+ .fill_screen = fill_screen,
+ .update_display = update_display,
+ .enable_display = NULL,
+ .set_invert_color = NULL,
+ .set_normal_color = NULL,
+ .set_contrast = NULL,
+ .scroll_right = NULL,
+ .scroll_left = NULL,
+ .scroll_diag_right = NULL,
+ .scroll_diag_left = NULL,
+ .stop_scroll = NULL,
+};
+
+/** Flag to monitor is this driver has been initialized. The
+ * oled_display_instance
+ * is only valid after initialized=true. */
+static bool initialized = false;
+
+sl_status_t oled_display_init(void)
+{
+ oled_display_instance.width = MIKROE_E_PAPER_WIDTH;
+ oled_display_instance.height = MIKROE_E_PAPER_HEIGHT;
+ oled_display_instance.driver = &sl_memlcd_driver_api;
+ initialized = true;
+ return SL_STATUS_OK;
+}
+
+static sl_status_t draw_pixel(int16_t x, int16_t y, uint16_t color)
+{
+ uint16_t off;
+ uint16_t pos;
+
+ if ((x >= 0) && (x < MIKROE_E_PAPER_WIDTH) && (y >= 0)
+ && (y < MIKROE_E_PAPER_HEIGHT)) {
+ pos = (y * (MIKROE_E_PAPER_WIDTH / 8)) + (x / 8);
+ off = 7 - (x % 8);
+ oled_frame_buffer[pos] &= ~(0x01 << off);
+ oled_frame_buffer[pos] |= ((color & 0x01) << off);
+ }
+ return SL_STATUS_OK;
+}
+
+static sl_status_t fill_screen(uint16_t color)
+{
+ uint16_t i;
+
+ /* Fill the display with the background color of the glib_context_t */
+ for (i = 0; i < sizeof(oled_frame_buffer); i++) {
+ oled_frame_buffer[i] = (uint8_t)color;
+ }
+ return SL_STATUS_OK;
+}
+
+static sl_status_t update_display(void)
+{
+ eink_154_xy_t xy;
+
+ xy.x_start = 0;
+ xy.y_start = 0;
+ xy.x_end = MIKROE_E_PAPER_WIDTH - 1;
+ xy.y_end = MIKROE_E_PAPER_HEIGHT - 1;
+
+ mikroe_e_paper_154_inch_set_memory_area(&xy);
+ mikroe_e_paper_154_inch_set_memory_pointer(0, 0);
+ mikroe_e_paper_154_inch_send_command(E_PAPER_CMD_WRITE_RAM);
+
+ for (uint16_t i = 0; i < sizeof(oled_frame_buffer); i++ )
+ {
+ mikroe_e_paper_154_inch_send_data(oled_frame_buffer[i]);
+ }
+ return mikroe_e_paper_154_inch_update_display();
+}
+
+const oled_display_t *oled_display_get(void)
+{
+ if (initialized) {
+ return &oled_display_instance;
+ } else {
+ return NULL;
+ }
+}
+
+static sl_status_t driver_init(void)
+{
+ return SL_STATUS_OK;
+}
diff --git a/driver/public/mikroe/lte_iot2_bg96/config/brd2703a/mikroe_lte_iot2_bg96_config.h b/driver/public/mikroe/lte_iot2_bg96/config/brd2703a/mikroe_lte_iot2_bg96_config.h
new file mode 100644
index 00000000..655eb951
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/config/brd2703a/mikroe_lte_iot2_bg96_config.h
@@ -0,0 +1,87 @@
+/***************************************************************************//**
+ * @file mikroe_lte_iot2_bg96_config.h
+ * @brief mikroe_lte_iot2_bg96_config.h
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_LTE_IOT2_BG96_CONFIG_H_
+#define MIKROE_LTE_IOT2_BG96_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "em_gpio.h"
+
+// <<< Use Configuration Wizard in Context Menu
+
+// LTE IOT2 BG96 Settings
+
+// Maximum AT Command Length
+// Default: 300
+#define CMD_MAX_SIZE 300
+
+// Size of buffer to receive AT Command response
+// Default: 300
+#define IN_BUFFER_SIZE 300
+
+// Size of queue to store at_cmd_desc_t
+// Default: 20
+#define CMD_Q_SIZE 20
+// end LTE IOT2 BG96 config
+
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// BG96_STA
+// $[GPIO_BG96_STA]
+#define BG96_STA_PORT gpioPortB
+#define BG96_STA_PIN 0
+// [GPIO_BG96_STA]$
+
+// BG96_PWK
+// $[GPIO_BG96_PWK]
+#define BG96_PWK_PORT gpioPortC
+#define BG96_PWK_PIN 8
+// [GPIO_BG96_PWK]$
+
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_LTE_IOT2_BG96_CONFIG_H_ */
diff --git a/driver/public/mikroe/lte_iot2_bg96/config/brd2703a/sl_iostream_usart_bg96_config.h b/driver/public/mikroe/lte_iot2_bg96/config/brd2703a/sl_iostream_usart_bg96_config.h
new file mode 100644
index 00000000..ee6881cf
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/config/brd2703a/sl_iostream_usart_bg96_config.h
@@ -0,0 +1,112 @@
+/***************************************************************************//**
+ * @file
+ * @brief IOSTREAM_USART Config.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+
+#ifndef SL_IOSTREAM_USART_BG96_CONFIG_H
+#define SL_IOSTREAM_USART_BG96_CONFIG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// USART settings
+
+// Baud rate
+// Default: 115200
+#define SL_IOSTREAM_USART_BG96_BAUDRATE 115200
+
+// Parity mode to use
+// No Parity
+// Even parity
+// Odd parity
+// Default: usartNoParity
+#define SL_IOSTREAM_USART_BG96_PARITY usartNoParity
+
+// Number of stop bits to use.
+// 0.5 stop bits
+// 1 stop bits
+// 1.5 stop bits
+// 2 stop bits
+// Default: usartStopbits1
+#define SL_IOSTREAM_USART_BG96_STOP_BITS usartStopbits1
+
+// Flow control
+// None
+// CTS
+// RTS
+// CTS/RTS
+// Software Flow control (XON/XOFF)
+// Default: usartHwFlowControlNone
+#define SL_IOSTREAM_USART_BG96_FLOW_CONTROL_TYPE usartHwFlowControlNone
+
+// Receive buffer size
+// Default: 32
+#define SL_IOSTREAM_USART_BG96_RX_BUFFER_SIZE 300
+
+// Convert \n to \r\n
+// It can be changed at runtime using the C API.
+// Default: 0
+#define SL_IOSTREAM_USART_BG96_CONVERT_BY_DEFAULT_LF_TO_CRLF 0
+
+// Restrict
+// the energy mode to allow the reception.
+// Default: 1
+// Limits the lowest energy mode the system can sleep to in order to keep
+// the reception on. May cause higher power consumption.
+#define SL_IOSTREAM_USART_BG96_RESTRICT_ENERGY_MODE_TO_ALLOW_RECEPTION 1
+
+//
+
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+// SL_IOSTREAM_USART_BG96
+// $[USART_SL_IOSTREAM_USART_BG96]
+#define SL_IOSTREAM_USART_BG96_PERIPHERAL USART0
+#define SL_IOSTREAM_USART_BG96_PERIPHERAL_NO 0
+
+// USART0 TX on PB01
+#define SL_IOSTREAM_USART_BG96_TX_PORT gpioPortD
+#define SL_IOSTREAM_USART_BG96_TX_PIN 4
+
+// USART0 RX on PB02
+#define SL_IOSTREAM_USART_BG96_RX_PORT gpioPortD
+#define SL_IOSTREAM_USART_BG96_RX_PIN 5
+
+// [USART_SL_IOSTREAM_USART_BG96]$
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver/public/mikroe/lte_iot2_bg96/config/brd4108a/mikroe_lte_iot2_bg96_config.h b/driver/public/mikroe/lte_iot2_bg96/config/brd4108a/mikroe_lte_iot2_bg96_config.h
new file mode 100644
index 00000000..b3d53e17
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/config/brd4108a/mikroe_lte_iot2_bg96_config.h
@@ -0,0 +1,87 @@
+/***************************************************************************//**
+ * @file mikroe_lte_iot2_bg96_config.h
+ * @brief mikroe_lte_iot2_bg96_config.h
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_LTE_IOT2_BG96_CONFIG_H_
+#define MIKROE_LTE_IOT2_BG96_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "em_gpio.h"
+
+// <<< Use Configuration Wizard in Context Menu
+
+// LTE IOT2 BG96 Settings
+
+// Maximum AT Command Length
+// Default: 300
+#define CMD_MAX_SIZE 300
+
+// Size of buffer to receive AT Command response
+// Default: 300
+#define IN_BUFFER_SIZE 300
+
+// Size of queue to store at_cmd_desc_t
+// Default: 20
+#define CMD_Q_SIZE 20
+// end LTE IOT2 BG96 config
+
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// BG96_STA
+// $[GPIO_BG96_STA]
+#define BG96_STA_PORT gpioPortB
+#define BG96_STA_PIN 0
+// [GPIO_BG96_STA]$
+
+// BG96_PWK
+// $[GPIO_BG96_PWK]
+#define BG96_PWK_PORT gpioPortC
+#define BG96_PWK_PIN 6
+// [GPIO_BG96_PWK]$
+
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_LTE_IOT2_BG96_CONFIG_H_ */
diff --git a/driver/public/mikroe/lte_iot2_bg96/config/brd4108a/sl_iostream_usart_bg96_config.h b/driver/public/mikroe/lte_iot2_bg96/config/brd4108a/sl_iostream_usart_bg96_config.h
new file mode 100644
index 00000000..c49ee600
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/config/brd4108a/sl_iostream_usart_bg96_config.h
@@ -0,0 +1,112 @@
+/***************************************************************************//**
+ * @file
+ * @brief IOSTREAM_USART Config.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+
+#ifndef SL_IOSTREAM_USART_BG96_CONFIG_H
+#define SL_IOSTREAM_USART_BG96_CONFIG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// USART settings
+
+// Baud rate
+// Default: 115200
+#define SL_IOSTREAM_USART_BG96_BAUDRATE 115200
+
+// Parity mode to use
+// No Parity
+// Even parity
+// Odd parity
+// Default: usartNoParity
+#define SL_IOSTREAM_USART_BG96_PARITY usartNoParity
+
+// Number of stop bits to use.
+// 0.5 stop bits
+// 1 stop bits
+// 1.5 stop bits
+// 2 stop bits
+// Default: usartStopbits1
+#define SL_IOSTREAM_USART_BG96_STOP_BITS usartStopbits1
+
+// Flow control
+// None
+// CTS
+// RTS
+// CTS/RTS
+// Software Flow control (XON/XOFF)
+// Default: usartHwFlowControlNone
+#define SL_IOSTREAM_USART_BG96_FLOW_CONTROL_TYPE usartHwFlowControlNone
+
+// Receive buffer size
+// Default: 32
+#define SL_IOSTREAM_USART_BG96_RX_BUFFER_SIZE 300
+
+// Convert \n to \r\n
+// It can be changed at runtime using the C API.
+// Default: 0
+#define SL_IOSTREAM_USART_BG96_CONVERT_BY_DEFAULT_LF_TO_CRLF 0
+
+// Restrict
+// the energy mode to allow the reception.
+// Default: 1
+// Limits the lowest energy mode the system can sleep to in order to keep
+// the reception on. May cause higher power consumption.
+#define SL_IOSTREAM_USART_BG96_RESTRICT_ENERGY_MODE_TO_ALLOW_RECEPTION 1
+
+//
+
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+// SL_IOSTREAM_USART_BG96
+// $[USART_SL_IOSTREAM_USART_BG96]
+#define SL_IOSTREAM_USART_BG96_PERIPHERAL USART1
+#define SL_IOSTREAM_USART_BG96_PERIPHERAL_NO 1
+
+// USART0 TX on PB01
+#define SL_IOSTREAM_USART_BG96_TX_PORT gpioPortB
+#define SL_IOSTREAM_USART_BG96_TX_PIN 1
+
+// USART0 RX on PB02
+#define SL_IOSTREAM_USART_BG96_RX_PORT gpioPortB
+#define SL_IOSTREAM_USART_BG96_RX_PIN 2
+
+// [USART_SL_IOSTREAM_USART_BG96]$
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver/public/mikroe/lte_iot2_bg96/config/brd4314a/mikroe_lte_iot2_bg96_config.h b/driver/public/mikroe/lte_iot2_bg96/config/brd4314a/mikroe_lte_iot2_bg96_config.h
new file mode 100644
index 00000000..b3d53e17
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/config/brd4314a/mikroe_lte_iot2_bg96_config.h
@@ -0,0 +1,87 @@
+/***************************************************************************//**
+ * @file mikroe_lte_iot2_bg96_config.h
+ * @brief mikroe_lte_iot2_bg96_config.h
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_LTE_IOT2_BG96_CONFIG_H_
+#define MIKROE_LTE_IOT2_BG96_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "em_gpio.h"
+
+// <<< Use Configuration Wizard in Context Menu
+
+// LTE IOT2 BG96 Settings
+
+// Maximum AT Command Length
+// Default: 300
+#define CMD_MAX_SIZE 300
+
+// Size of buffer to receive AT Command response
+// Default: 300
+#define IN_BUFFER_SIZE 300
+
+// Size of queue to store at_cmd_desc_t
+// Default: 20
+#define CMD_Q_SIZE 20
+// end LTE IOT2 BG96 config
+
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// BG96_STA
+// $[GPIO_BG96_STA]
+#define BG96_STA_PORT gpioPortB
+#define BG96_STA_PIN 0
+// [GPIO_BG96_STA]$
+
+// BG96_PWK
+// $[GPIO_BG96_PWK]
+#define BG96_PWK_PORT gpioPortC
+#define BG96_PWK_PIN 6
+// [GPIO_BG96_PWK]$
+
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_LTE_IOT2_BG96_CONFIG_H_ */
diff --git a/driver/public/mikroe/lte_iot2_bg96/config/brd4314a/sl_iostream_usart_bg96_config.h b/driver/public/mikroe/lte_iot2_bg96/config/brd4314a/sl_iostream_usart_bg96_config.h
new file mode 100644
index 00000000..c49ee600
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/config/brd4314a/sl_iostream_usart_bg96_config.h
@@ -0,0 +1,112 @@
+/***************************************************************************//**
+ * @file
+ * @brief IOSTREAM_USART Config.
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+
+#ifndef SL_IOSTREAM_USART_BG96_CONFIG_H
+#define SL_IOSTREAM_USART_BG96_CONFIG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// USART settings
+
+// Baud rate
+// Default: 115200
+#define SL_IOSTREAM_USART_BG96_BAUDRATE 115200
+
+// Parity mode to use
+// No Parity
+// Even parity
+// Odd parity
+// Default: usartNoParity
+#define SL_IOSTREAM_USART_BG96_PARITY usartNoParity
+
+// Number of stop bits to use.
+// 0.5 stop bits
+// 1 stop bits
+// 1.5 stop bits
+// 2 stop bits
+// Default: usartStopbits1
+#define SL_IOSTREAM_USART_BG96_STOP_BITS usartStopbits1
+
+// Flow control
+// None
+// CTS
+// RTS
+// CTS/RTS
+// Software Flow control (XON/XOFF)
+// Default: usartHwFlowControlNone
+#define SL_IOSTREAM_USART_BG96_FLOW_CONTROL_TYPE usartHwFlowControlNone
+
+// Receive buffer size
+// Default: 32
+#define SL_IOSTREAM_USART_BG96_RX_BUFFER_SIZE 300
+
+// Convert \n to \r\n
+// It can be changed at runtime using the C API.
+// Default: 0
+#define SL_IOSTREAM_USART_BG96_CONVERT_BY_DEFAULT_LF_TO_CRLF 0
+
+// Restrict
+// the energy mode to allow the reception.
+// Default: 1
+// Limits the lowest energy mode the system can sleep to in order to keep
+// the reception on. May cause higher power consumption.
+#define SL_IOSTREAM_USART_BG96_RESTRICT_ENERGY_MODE_TO_ALLOW_RECEPTION 1
+
+//
+
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+// SL_IOSTREAM_USART_BG96
+// $[USART_SL_IOSTREAM_USART_BG96]
+#define SL_IOSTREAM_USART_BG96_PERIPHERAL USART1
+#define SL_IOSTREAM_USART_BG96_PERIPHERAL_NO 1
+
+// USART0 TX on PB01
+#define SL_IOSTREAM_USART_BG96_TX_PORT gpioPortB
+#define SL_IOSTREAM_USART_BG96_TX_PIN 1
+
+// USART0 RX on PB02
+#define SL_IOSTREAM_USART_BG96_RX_PORT gpioPortB
+#define SL_IOSTREAM_USART_BG96_RX_PIN 2
+
+// [USART_SL_IOSTREAM_USART_BG96]$
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_core.h b/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_core.h
new file mode 100644
index 00000000..5cff55fe
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_core.h
@@ -0,0 +1,182 @@
+/***************************************************************************//**
+ * @file at_parser_core.h
+ * @brief header file for AT command parser core driver
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#ifndef AT_PARSER_CORE_H_
+#define AT_PARSER_CORE_H_
+#include "sl_status.h"
+#include "at_parser_platform.h"
+
+/******************************************************************************
+ ****************************** MACROS ************************************
+ *****************************************************************************/
+#define AT_DEFAULT_TIMEOUT 15000
+#define AT_OPEN_TIMEOUT 6000
+#define AT_SEND_TIMEOUT 20000
+#define AT_SMS_TEXT_TIMEOUT 120000
+
+/******************************************************************************
+ ************************** TYPE DEFINITIONS ******************************
+ *****************************************************************************/
+typedef enum {
+ SCH_READY = 0, SCH_SENDING, SCH_PROCESSED, SCH_ERROR,
+} at_cmd_scheduler_state_t;
+
+typedef struct {
+ sl_status_t status;
+ uint16_t error_code;
+ uint8_t response_data[CMD_MAX_SIZE];
+} at_scheduler_status_t;
+
+/**************************************************************************//**
+ * @brief
+ * AT parser core initialization
+ *****************************************************************************/
+void at_parser_init(void);
+
+/**************************************************************************//**
+ * @brief
+ * AT parser output object initialization.
+ * Sets the status to SL_STATUS_NOT_INITIALIZED.
+ * Sets the error code to 0.
+ * Clears the response buffer.
+ *
+ * @param[in] output_object
+ * Pointer to the output object which should be initialized.
+ *
+ *****************************************************************************/
+void at_parser_init_output_object(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * AT parser extend command.
+ * Extends the command sting of the command descriptor.
+ *
+ * @param[in] at_cmd_descriptor
+ * Pointer to the command descriptor.
+ *
+ * @param[in] data_to_add
+ * String which the command string should be extended with.
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_INVALID_PARAMETER if at_cmd_descriptor == NULL or
+ * data_to_add == NULL
+ *****************************************************************************/
+sl_status_t at_parser_extend_cmd(at_cmd_desc_t *at_cmd_descriptor,
+ uint8_t *data_to_add);
+
+/**************************************************************************//**
+ * @brief
+ * Start AT command scheduler.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the status and response.
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *
+ *****************************************************************************/
+sl_status_t at_parser_start_scheduler(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * Get scheduler state.
+ *
+ * @return
+ * Actual state of the command scheduler.
+ * SCH_READY, SCH_SENDING, SCH_PROCESSED, SCH_ERROR
+ *
+ *****************************************************************************/
+at_cmd_scheduler_state_t at_parser_get_scheduler_state(void);
+
+/**************************************************************************//**
+ * @brief
+ * Add a command descriptor to the command queue.
+ * Command descriptor MUST be allocated until the scheduler runs.
+ *
+ * @param[in] at_cmd_descriptor
+ * Pointer to the command descriptor to add.
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_ALLOCATION_FAILED if command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if at_cmd_descriptor == NULL
+ *
+ *****************************************************************************/
+sl_status_t at_parser_add_cmd_to_q(at_cmd_desc_t *at_cmd_descriptor);
+
+/**************************************************************************//**
+ * @brief
+ * Clears the command string in the command descriptor.
+ *
+ * @param[in] at_cmd_descriptor
+ * Pointer to the command descriptor to clear.
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_INVALID_PARAMETER if at_cmd_descriptor == NULL
+ *****************************************************************************/
+sl_status_t at_parser_clear_cmd(at_cmd_desc_t *at_cmd_descriptor);
+
+/**************************************************************************//**
+ * @brief
+ * AT parser process function.
+ * This function SHALL be called periodically in the main loop.
+ *
+ *****************************************************************************/
+void at_parser_process(void);
+
+/******************************************************************************
+ ******************* LINE CALLBACK FUNCTIONS ******************************
+ *****************************************************************************/
+void at_imei_cb(uint8_t *new_line, uint8_t call_number);
+void at_infor_cb(uint8_t *new_line, uint8_t call_number);
+void at_te_gsm_cb(uint8_t *new_line, uint8_t call_number);
+void at_service_domain_cb(uint8_t *new_line, uint8_t call_number);
+void set_sms_mode_cb(uint8_t *new_line, uint8_t call_number);
+void at_sms_send_command_cb(uint8_t *new_line, uint8_t call_number);
+void at_sms_send_data_cb(uint8_t *new_line, uint8_t call_number);
+void at_set_sim_apn_cb(uint8_t *new_line, uint8_t call_number);
+void at_gps_start_stop_cb(uint8_t *new_line, uint8_t call_number);
+void at_ok_error_cb(uint8_t *new_line, uint8_t call_number);
+void at_cops_cb(uint8_t *new_line, uint8_t call_number);
+void at_recv_cb(uint8_t *new_line, uint8_t call_number);
+void at_send_cb(uint8_t *new_line, uint8_t call_number);
+void at_data_cb(uint8_t *new_line, uint8_t call_number);
+void at_ip_cb(uint8_t *new_line, uint8_t call_number);
+void at_qistate_cb(uint8_t *new_line, uint8_t call_number);
+void at_open_cb(uint8_t *new_line, uint8_t call_number);
+void at_gpsloc_cb(uint8_t *new_line, uint8_t call_number);
+
+#endif /* AT_PARSER_CORE_H_ */
diff --git a/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_events.h b/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_events.h
new file mode 100644
index 00000000..d7022b7c
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_events.h
@@ -0,0 +1,76 @@
+/***************************************************************************//**
+ * @file at_parser_events.h
+ * @brief header file for AT parser event listener
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+
+#ifndef AT_PARSER_EVENTS_H_
+#define AT_PARSER_EVENTS_H_
+
+#include "sl_status.h"
+
+/**************************************************************************//**
+ * @brief
+ * AT parser event listener listen function.
+ * This function can handle only one event at the same time.
+ *
+ * @param[in] event_flag
+ * Pointer to the flag to listen to.
+ *
+ * @param[in] event_flag_ok_value
+ * The decent flag value when the callback function should be called.
+ *
+ * @param[out] handle
+ * Pointer to a callback function.
+ *
+ * @param[in] handler_data
+ * Pointer to the data which will be given as callback parameter.
+ *
+ * @return
+ * SL_STATUS_OK if event listener has been set.
+ * SL_STATUS_ALLOCATION_FAILED if listener is already running.
+ *
+ *****************************************************************************/
+sl_status_t at_listen_event(uint8_t *event_flag,
+ uint8_t event_ok_value,
+ void (*handle)(void *),
+ void *handler_data);
+
+/**************************************************************************//**
+ * @brief
+ * AT parser event listener process function.
+ * This function SHALL be called periodically in the main loop.
+ *
+ *****************************************************************************/
+void at_event_process(void);
+
+#endif /* AT_PARSER_EVENTS_H_ */
diff --git a/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_platform.h b/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_platform.h
new file mode 100644
index 00000000..36bd437f
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_platform.h
@@ -0,0 +1,130 @@
+/***************************************************************************//**
+ * @file at_parser_platform.h
+ * @brief header file for AT command parser platform driver
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+
+#ifndef AT_PARSER_PLATFORM_H_
+#define AT_PARSER_PLATFORM_H_
+#include "sl_status.h"
+#include "mikroe_lte_iot2_bg96_config.h"
+#include "em_cmu.h"
+#include "em_eusart.h"
+
+/*******************************************************************************
+ ******************************** MACROS ***********************************
+ ******************************************************************************/
+
+/*******************************************************************************
+ ************************** TYPE DEFINITIONS *******************************
+ ******************************************************************************/
+typedef void (*ln_cb_t)(uint8_t *response, uint8_t call_number);
+
+typedef enum {
+ NOT_INITIALIZED = 0, READY, TRANSMIT
+} at_platform_status_t;
+
+typedef struct {
+ uint8_t cms_string[CMD_MAX_SIZE];
+ ln_cb_t ln_cb;
+ uint32_t timeout_ms;
+} at_cmd_desc_t;
+
+/**************************************************************************//**
+ * @brief
+ * CMU initialization.
+ *****************************************************************************/
+void initCMU(void);
+
+/**************************************************************************//**
+ * @brief
+ * GPIO initialization.
+ *****************************************************************************/
+void initGPIO(void);
+
+/**************************************************************************//**
+ * @brief
+ * Initialization of platform driver.
+ *
+ * @param[in] line_callback
+ * Callback function for new line (and ">" character for special commands).
+ *
+ *****************************************************************************/
+void at_platform_init(ln_cb_t line_callback);
+
+/**************************************************************************//**
+ * @brief
+ * Check ready status of platform driver.
+ *
+ *****************************************************************************/
+sl_status_t at_platform_check_device_ready();
+
+/**************************************************************************//**
+* @brief
+* Platform driver send command function.
+* This function adds \r to the command string.
+* Command string SHALL be allocated until command is sent.
+* This function uses UART TX and RX interrupt.
+*
+* @param[in] cmd
+* Pointer to the command to send.
+*
+* @param[in] timeout_ms
+* Timeout for the command in milliseconds.
+*
+* @return
+* SL_STATUS_OK if there are no errors.
+* SL_STATUS_INVALID_PARAMETER if cmd == NULL.
+******************************************************************************/
+sl_status_t at_platform_send_cmd(volatile uint8_t *cmd,
+ volatile uint16_t timeout_ms);
+
+/**************************************************************************//**
+ * @brief
+ * Platform driver finish function.
+ * Used to end ongoing communication.
+ * Stops timeout and hardware interrupts.
+ *
+ *****************************************************************************/
+void at_platform_finish_cmd(void);
+
+/**************************************************************************//**
+ * @brief
+ * Platform driver process function.
+ * This function removes \r and \n characters.
+ * Calls global callback if it is defined.
+ * Used to process incoming uart rx data
+ *
+ *****************************************************************************/
+void at_platform_process(void);
+
+#endif /* AT_PARSER_PLATFORM_H_ */
diff --git a/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_utility.h b/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_utility.h
new file mode 100644
index 00000000..0cf283c5
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/inc/at_parser_utility.h
@@ -0,0 +1,49 @@
+/***************************************************************************//**
+ * @file at_parser_utility.h
+ * @brief header file for AT command parser utility functions
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+
+#ifndef AT_PARSER_UTILITY_H_
+#define AT_PARSER_UTILITY_H_
+
+/**************************************************************************//**
+ * @brief
+ * Validation function indicates error in a command chain.
+ * If any function in the command chain throws error it
+ * is propagated throughout the chain.
+ *
+ *****************************************************************************/
+#define validate(error, \
+ fn_result) error = (SL_STATUS_OK == error)?(fn_result):(error)
+
+#endif /* AT_PARSER_UTILITY_H_ */
diff --git a/driver/public/mikroe/lte_iot2_bg96/inc/mikroe_bg96.h b/driver/public/mikroe/lte_iot2_bg96/inc/mikroe_bg96.h
new file mode 100644
index 00000000..07c558f6
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/inc/mikroe_bg96.h
@@ -0,0 +1,436 @@
+/***************************************************************************//**
+ * @file mikroe_bg96.h
+ * @brief mikroe_bg96.h
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_BG96_H_
+#define MIKROE_BG96_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include "sl_status.h"
+#include "at_parser_core.h"
+#include
+#include
+#include "em_cmu.h"
+#include "em_usart.h"
+
+/*******************************************************************************
+ ******************************** MACROS ***********************************
+ ******************************************************************************/
+#define BG96_GPIO_H_TIME 1000
+#define BG96_TIMEOUT_MS 15000
+#define DATA_MAX_LENGTH 80u
+
+typedef enum {
+ set_sms_mode_pdu = 0,
+ set_sms_mode_text,
+}set_sms_mode_t;
+
+typedef enum {
+ service_domain_type_PSOnly_e = 0,
+ service_domain_type_CS_and_PS_e,
+}config_service_domain_type_t;
+
+/*******************************************************************************
+ ***************************** STRUCTURES **********************************
+ ******************************************************************************/
+typedef struct {
+ uint8_t socket;
+ uint16_t port;
+ uint8_t port_type[15];
+ uint8_t *address;
+} bg96_nb_connection_t;
+
+typedef struct {
+ uint8_t phone_number[32];
+ uint8_t sms_text_content[256];
+}bg96_sms_text_t;
+
+typedef struct {
+ uint8_t service_center_number[32];
+ uint8_t phone_number[32];
+ uint8_t sms_text_content[256];
+}bg96_sms_pdu_t;
+
+/**************************************************************************//**
+ * @brief
+ * BG96 module initialize function.
+ *
+ *****************************************************************************/
+void bg96_init (void);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 is alive status getter function.
+ *
+ *****************************************************************************/
+bool bg96_is_alive (void);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 module sleep function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if wake-up initialization was successful.
+ * SL_STATUS_BUSY if sleep/wake up sequence has been already started
+ * SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG timer error.
+ * SL_STATUS_INVALID_PARAMETER timer related error.
+ *****************************************************************************/
+sl_status_t bg96_sleep (at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 module wake up function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if wake-up initialization was successful.
+ * SL_STATUS_BUSY if sleep/wake up sequence has been already started.
+ * SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG timer error.
+ * SL_STATUS_INVALID_PARAMETER timer related error.
+ *****************************************************************************/
+sl_status_t bg96_wake_up (at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * Initialization of GNSS function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_gnss_start(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * Get the GNSS location string.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_gnss_get_position(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * Stop GNSS function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_gnss_stop(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT initialization.
+ *
+ *****************************************************************************/
+void bg96_nb_init(void);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT open a TCP or UDP connection.
+ *
+ * @param[in] connection
+ * Pointer to the connection descriptor structure.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_nb_open_connection(bg96_nb_connection_t *connection,
+ at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT network registration.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_network_registration(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT close client connection.
+ *
+ * @param[in] connection
+ * Pointer to the connection descriptor structure.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_nb_close_connection(bg96_nb_connection_t *connection,
+ at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB send data function.
+ *
+ * @param[in] connection
+ * Pointer to the connection descriptor structure.
+ *
+ * @param[in] data
+ * Pointer to the data to send.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_nb_send_data(bg96_nb_connection_t *connection,
+ uint8_t *data,
+ at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT receive data function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_nb_receive_data(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT read actual IP address function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_read_ip(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT get actual operator function.
+ *
+ * @param[in] connection
+ * Pointer to the connection descriptor structure.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_get_operator(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT read HW IMEI number.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data..
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_read_imei(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 module get information function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_read_infor (at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT set TE character set as GSM.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data..
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_set_te_gsm(at_scheduler_status_t *output_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT Configure the service domain of UE.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @param[in] type
+ * Variable to set type of the service domain
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_config_service_domain(at_scheduler_status_t *output_object,
+ config_service_domain_type_t type);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT set SMS mode
+ *
+ * @param[in] mode
+ * Variable to set sms mode
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_set_sms_mode(at_scheduler_status_t *output_object,
+ set_sms_mode_t mode);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT send SMS Text
+ *
+ * @param[in] sms_text_object
+ * Pointer to the sms text descriptor structure.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_send_sms_text(at_scheduler_status_t *output_object,
+ bg96_sms_text_t *sms_text_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT send SMS PDU
+ *
+ * @param[in] sms_pdu_object
+ * Pointer to the sms pdu descriptor structure.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_send_sms_pdu(at_scheduler_status_t *output_object,
+ bg96_sms_pdu_t *sms_pdu_object);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT set SIM APN
+ *
+ * @param[in] sim_apn
+ * Pointer to the SIM APN descriptor .
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ *****************************************************************************/
+sl_status_t bg96_set_sim_apn(at_scheduler_status_t *output_object,
+ uint8_t *sim_apn);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_BG96_H_ */
diff --git a/driver/public/mikroe/lte_iot2_bg96/src/at_parser_core.c b/driver/public/mikroe/lte_iot2_bg96/src/at_parser_core.c
new file mode 100644
index 00000000..a8d64631
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/src/at_parser_core.c
@@ -0,0 +1,842 @@
+/***************************************************************************//**
+ * @file at_parser_core.c
+ * @brief AT command parser core driver source
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#include "at_parser_core.h"
+#include
+#include "app_queue.h"
+#include
+#include
+
+/******************************************************************************
+ ********************** MACRO UTILITY FUNCTIONS ***************************
+ *****************************************************************************/
+#define has_substring(container, substr) \
+ (NULL != strstr((const char *) new_line, (const char *)substr))
+
+APP_QUEUE(cmd_q, at_cmd_desc_t, CMD_Q_SIZE);
+static at_cmd_scheduler_state_t sch_state = SCH_READY;
+static at_scheduler_status_t *global_status;
+
+static void at_parser_scheduler_next_cmd();
+static void at_parser_scheduler_error(uint8_t error_code);
+static void general_platform_cb(uint8_t *data, uint8_t call_number);
+static void at_parser_report_data(uint8_t *data);
+static void at_parser_get_ip(uint8_t *response, uint8_t *ip_output);
+
+/**************************************************************************//**
+ * @brief
+ * AT parser core initialization
+ *****************************************************************************/
+void at_parser_init()
+{
+ APP_QUEUE_INIT(&cmd_q, at_cmd_desc_t, CMD_Q_SIZE);
+ at_platform_init(general_platform_cb);
+}
+
+/**************************************************************************//**
+ * @brief
+ * AT parser output object initialization.
+ * Sets the status to SL_STATUS_NOT_INITIALIZED.
+ * Sets the error code to 0.
+ * Clears the response buffer.
+ *
+ * @param[in] output_object
+ * Pointer to the output object which should be initialized.
+ *
+ *****************************************************************************/
+void at_parser_init_output_object(at_scheduler_status_t *output_object)
+{
+ if (output_object != NULL) {
+ output_object->error_code = 0;
+ output_object->status = SL_STATUS_NOT_INITIALIZED;
+ memset((void *) output_object->response_data, '\0', CMD_MAX_SIZE);
+ }
+}
+
+/**************************************************************************//**
+ * @brief
+ * AT parser extend command.
+ * Extends the command sting of the command descriptor.
+ *
+ * @param[in] at_cmd_descriptor
+ * Pointer to the command descriptor.
+ *
+ * @param[in] data_to_add
+ * String which the command string should be extended with.
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_INVALID_PARAMETER if at_cmd_descriptor == NULL or
+ * data_to_add == NULL
+ *
+ *****************************************************************************/
+sl_status_t at_parser_extend_cmd(at_cmd_desc_t *at_cmd_descriptor,
+ uint8_t *data_to_add)
+{
+ if ((at_cmd_descriptor != NULL) && (data_to_add != NULL)) {
+ size_t sum_length = sl_strlen((char *) at_cmd_descriptor->cms_string);
+ sum_length += sl_strlen((char *) data_to_add);
+
+ if (sum_length <= CMD_MAX_SIZE) {
+ sl_strcat_s((char *) at_cmd_descriptor->cms_string,
+ CMD_MAX_SIZE,
+ (const char *) data_to_add);
+ return SL_STATUS_OK;
+ }
+ }
+
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Start AT command scheduler.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the status and response.
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *
+ *****************************************************************************/
+sl_status_t at_parser_start_scheduler(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ static at_cmd_desc_t at_cmd_descriptor;
+
+ if (SCH_READY != sch_state) {
+ return SL_STATUS_BUSY;
+ }
+ if (app_queue_is_empty(&cmd_q)) {
+ return SL_STATUS_OK;
+ }
+
+ sch_state = SCH_SENDING;
+ global_status = output_object;
+ at_parser_init_output_object(global_status);
+ app_queue_peek(&cmd_q, (uint8_t *)&at_cmd_descriptor);
+ return at_platform_send_cmd(at_cmd_descriptor.cms_string,
+ at_cmd_descriptor.timeout_ms);
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Get scheduler state.
+ *
+ * @return
+ * Actual state of the command scheduler.
+ * SCH_READY, SCH_SENDING, SCH_PROCESSED, SCH_ERROR
+ *
+ *****************************************************************************/
+at_cmd_scheduler_state_t at_parser_get_scheduler_state()
+{
+ return sch_state;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Add a command descriptor to the command queue.
+ * Command descriptor MUST be allocated until the scheduler runs.
+ *
+ * @param[in] at_cmd_descriptor
+ * Pointer to the command descriptor to add.
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_ALLOCATION_FAILED if command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if at_cmd_descriptor == NULL
+ *
+ *****************************************************************************/
+sl_status_t at_parser_add_cmd_to_q(at_cmd_desc_t *at_cmd_descriptor)
+{
+ if (app_queue_is_full(&cmd_q)) {
+ return SL_STATUS_ALLOCATION_FAILED;
+ }
+
+ if (at_cmd_descriptor == NULL) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ return app_queue_add(&cmd_q, (uint8_t *)at_cmd_descriptor);
+}
+
+/**************************************************************************//**
+ * @brief
+ * Clears the command string in the command descriptor.
+ *
+ * @param[in] at_cmd_descriptor
+ * Pointer to the command descriptor to clear.
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_INVALID_PARAMETER if at_cmd_descriptor == NULL
+ *****************************************************************************/
+sl_status_t at_parser_clear_cmd(at_cmd_desc_t *at_cmd_descriptor)
+{
+ if (at_cmd_descriptor != NULL) {
+ memset(at_cmd_descriptor->cms_string, 0, CMD_MAX_SIZE);
+ return SL_STATUS_OK;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * AT parser process function.
+ * This function SHALL be called periodically in the main loop.
+ *
+ *****************************************************************************/
+void at_parser_process(void)
+{
+ static at_cmd_desc_t at_cmd_descriptor;
+
+ switch (sch_state) {
+ case SCH_PROCESSED:
+ // remove previous command
+ app_queue_remove(&cmd_q, (uint8_t *)&at_cmd_descriptor);
+ at_platform_finish_cmd();
+ if (!app_queue_is_empty(&cmd_q)) {
+ app_queue_peek(&cmd_q, (uint8_t *)&at_cmd_descriptor);
+ at_platform_send_cmd(at_cmd_descriptor.cms_string,
+ at_cmd_descriptor.timeout_ms);
+ sch_state = SCH_SENDING;
+ } else {
+ global_status->status = SL_STATUS_OK;
+ sch_state = SCH_READY;
+ }
+ break;
+ case SCH_ERROR:
+ at_platform_finish_cmd();
+ while (!app_queue_is_empty(&cmd_q)) {
+ app_queue_remove(&cmd_q, (uint8_t *)&at_cmd_descriptor);
+ }
+ global_status->status = SL_STATUS_OK;
+ sch_state = SCH_READY;
+ break;
+ case SCH_READY:
+ break;
+ case SCH_SENDING:
+ break;
+ }
+}
+
+/**************************************************************************//**
+ * @brief
+ * General platfrom core callback function.
+ * Called in case of new line or timeout.
+ *
+ * @param[in] data
+ * Pointer to the data received in an new line.
+ *
+ * @param[in] call_number
+ * Number of received new lines.
+ * Is 0 if timeout occurred
+ *
+ *****************************************************************************/
+static void general_platform_cb(uint8_t *data, uint8_t call_number)
+{
+ static at_cmd_desc_t at_cmd_descriptor;
+ if (!app_queue_is_empty(&cmd_q)) {
+ app_queue_peek(&cmd_q, (uint8_t *)&at_cmd_descriptor);
+
+ // call number == 0 means timeout occurred
+ if (call_number == 0) {
+ at_platform_finish_cmd();
+ at_parser_scheduler_error(SL_STATUS_TIMEOUT);
+ } else {
+ if (at_cmd_descriptor.ln_cb != NULL) {
+ // call line callback of the command descriptor if available
+ at_cmd_descriptor.ln_cb(data, call_number);
+ }
+ }
+ }
+}
+
+static void at_parser_scheduler_next_cmd()
+{
+ sch_state = SCH_PROCESSED;
+}
+
+static void at_parser_scheduler_error(uint8_t error_code)
+{
+ global_status->error_code = error_code;
+ sch_state = SCH_ERROR;
+}
+
+/*******************************************************************************
+ ********************** PREDEFINED LINE CALLBACKS **************************
+ ******************************************************************************/
+void at_imei_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (!has_substring(new_line, "AT+GSN")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ at_parser_report_data(new_line);
+ break;
+ case 3:
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_infor_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (!has_substring(new_line, "ATI")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ break;
+ case 3:
+ break;
+ case 4:
+ if (has_substring(new_line, "Revision:")) {
+ at_parser_report_data(new_line);
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 5:
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_te_gsm_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (!has_substring(new_line, "AT+CSCS=")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_service_domain_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (!has_substring(new_line, "+QCFG=\"servicedomain\"")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void set_sms_mode_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (!has_substring(new_line, "AT+CMGF=")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (has_substring(new_line, "OK")) {
+ at_parser_report_data(new_line);
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_sms_send_command_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (has_substring(new_line, "+CMS ERROR:")
+ || has_substring(new_line, "ERROR")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (has_substring(new_line, ">")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_sms_send_data_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ case 2:
+ if (has_substring(new_line, "+CMS ERROR:")
+ || has_substring(new_line, "ERROR")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+
+ if (has_substring(new_line, "+CMGS:")) {
+ at_parser_report_data(new_line);
+ }
+ break;
+ case 3:
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_set_sim_apn_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (!has_substring(new_line, "AT+CGDCONT")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (has_substring(new_line, "OK")) {
+ at_parser_report_data(new_line);
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_gps_start_stop_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if ((!has_substring(new_line,
+ "AT+QGPS="))
+ && (!has_substring(new_line, "AT+QGPSEND"))) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (has_substring(new_line, "OK")) {
+ at_parser_report_data(new_line);
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_ok_error_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (has_substring(new_line, "OK")) {
+ at_parser_report_data(new_line);
+ at_parser_scheduler_next_cmd();
+ }
+ if (has_substring(new_line, "ERROR")) {
+ at_parser_report_data(new_line);
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_cops_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ at_parser_report_data(new_line);
+ if (!has_substring(new_line, "+COPS:")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_recv_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ uint8_t *space_ptr;
+ uint32_t qird_data;
+ static bool data_available = false;
+
+ switch (call_number) {
+ case 1:
+ if (!has_substring(new_line, "+QIRD:")) {
+ at_parser_report_data(new_line);
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ } else {
+ space_ptr = (uint8_t *) strchr((const char *) new_line, ' ');
+ if (space_ptr != NULL) {
+ qird_data =
+ (uint32_t) strtol((const char *) (++space_ptr), NULL, 10);
+ if (qird_data > 0) {
+ data_available = true;
+ }
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ }
+ break;
+ case 2:
+ if (data_available) {
+ at_parser_report_data(new_line);
+ } else {
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ }
+ data_available = false;
+ break;
+ case 3:
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_send_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (has_substring(new_line, ">")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_data_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (!has_substring(new_line, " ")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (!has_substring(new_line, "SEND OK")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 3:
+ if (!has_substring(new_line, "+QIURC:")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 4:
+ if (!has_substring(new_line, "[")) {
+ at_parser_report_data(new_line);
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 5:
+ if (!has_substring(new_line, "+QIURC:")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_ip_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ if (has_substring(new_line, "+QIACT:")) {
+ at_parser_get_ip(new_line, global_status->response_data);
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_qistate_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ switch (call_number) {
+ case 1:
+ at_parser_report_data(new_line);
+ if (!has_substring(new_line, "+QISTATE:")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_open_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ // wait OK
+ // wait +QIOPEN: 0,0 if second parameter != 0 then error
+ uint8_t *coma;
+ uint32_t error_code;
+
+ switch (call_number) {
+ case 1:
+ if (!has_substring(new_line, "OK")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ at_parser_report_data(new_line);
+ if (has_substring(new_line, "+QIOPEN:")) {
+ coma = (uint8_t *) strchr((const char *) new_line, ',');
+ if (NULL != coma) {
+ error_code = strtol((const char *) (++coma), NULL, 10);
+ if (error_code != 0) {
+ at_parser_report_data(new_line);
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ } else {
+ at_parser_scheduler_next_cmd();
+ }
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+void at_gpsloc_cb(uint8_t *new_line, uint8_t call_number)
+{
+ if (new_line != NULL) {
+ // wait for +QGPSLOC: ...
+ // wait OK
+ switch (call_number) {
+ case 1:
+ if (!has_substring(new_line, "AT+QGPSLOC?")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+ case 2:
+ if (!has_substring(new_line, "+QGPSLOC:")) {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ } else {
+ at_parser_report_data(new_line);
+ }
+ break;
+ case 3:
+ if (has_substring(new_line, "OK")) {
+ at_parser_scheduler_next_cmd();
+ } else {
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ }
+ break;
+
+ default:
+ at_parser_scheduler_error(SL_STATUS_FAIL);
+ break;
+ }
+ }
+}
+
+static void at_parser_report_data(uint8_t *data)
+{
+ if ((global_status != NULL) && (data != NULL)) {
+ size_t data_length = sl_strlen((char *) data);
+ if (CMD_MAX_SIZE >= data_length) {
+ sl_strcpy_s((char *) global_status->response_data, CMD_MAX_SIZE,
+ (const char *) data);
+ } else {
+ memcpy(global_status->response_data, data, CMD_MAX_SIZE);
+ global_status->response_data[CMD_MAX_SIZE - 1] = '\0';
+ }
+ }
+}
+
+static void at_parser_get_ip(uint8_t *response, uint8_t *ip_output)
+{
+ if ((response != NULL) && (ip_output != NULL)) {
+ uint8_t *first_quote, *second_quote;
+ uint32_t ip_length;
+
+ first_quote = (uint8_t *) strchr((const char *) response, (int) '\"');
+ if (first_quote != NULL) {
+ first_quote++;
+ second_quote = (uint8_t *) strchr((const char *) first_quote, (int) '\"');
+ if (second_quote != NULL) {
+ ip_length = (uint32_t) second_quote - (uint32_t) first_quote;
+ ip_length--;
+ memcpy(ip_output, first_quote, ip_length);
+ ip_output[ip_length] = '\0';
+ }
+ }
+ }
+}
diff --git a/driver/public/mikroe/lte_iot2_bg96/src/at_parser_events.c b/driver/public/mikroe/lte_iot2_bg96/src/at_parser_events.c
new file mode 100644
index 00000000..4b0e8822
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/src/at_parser_events.c
@@ -0,0 +1,98 @@
+/***************************************************************************//**
+ * @file at_parser_events.c
+ * @brief source for AT parser event listener
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+
+#include "at_parser_events.h"
+#include
+#include
+
+static void (*global_handle)();
+static uint8_t global_ok_value;
+static uint8_t *global_event_flag;
+static bool event_handled = true;
+static void *global_handler_data;
+
+/**************************************************************************//**
+ * @brief
+ * AT parser event listener listen function.
+ * This function can handle only one event at the same time.
+ *
+ * @param[in] event_flag
+ * Pointer to the flag to listen to.
+ *
+ * @param[in] event_flag_ok_value
+ * The decent flag value when the callback function should be called.
+ *
+ * @param[out] handle
+ * Pointer to a callback function.
+ *
+ * @param[in] handler_data
+ * Pointer to the data which will be given as callback parameter.
+ *
+ * @return
+ * SL_STATUS_OK if event listener has been set.
+ * SL_STATUS_ALLOCATION_FAILED if listener is already running.
+ *
+ *****************************************************************************/
+sl_status_t at_listen_event(uint8_t *event_flag,
+ uint8_t event_ok_value,
+ void (*handle)(void *),
+ void *handler_data)
+{
+ global_event_flag = event_flag;
+ global_ok_value = event_ok_value;
+ global_handler_data = handler_data;
+
+ if ((handle != NULL) && (event_handled == true)) {
+ global_handle = handle;
+ event_handled = false;
+ return SL_STATUS_OK;
+ }
+ return SL_STATUS_ALLOCATION_FAILED;
+}
+
+/**************************************************************************//**
+ * @brief
+ * AT parser event listener process function.
+ * This function SHALL be called periodically in the main loop.
+ *
+ *****************************************************************************/
+void at_event_process(void)
+{
+ if ((!event_handled)
+ && (*global_event_flag == global_ok_value) && (global_handle != NULL)) {
+ global_handle(global_handler_data);
+ event_handled = true;
+ }
+}
diff --git a/driver/public/mikroe/lte_iot2_bg96/src/at_parser_platform.c b/driver/public/mikroe/lte_iot2_bg96/src/at_parser_platform.c
new file mode 100644
index 00000000..bf5d1da7
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/src/at_parser_platform.c
@@ -0,0 +1,242 @@
+/***************************************************************************//**
+ * @file at_parser_platform.c
+ * @brief AT command parser platform driver source
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+
+#include "at_parser_platform.h"
+#include "sl_iostream.h"
+#include "sl_iostream_init_instances.h"
+#include "sl_iostream_handles.h"
+#include "sl_sleeptimer.h"
+#include
+#include "mikroe_lte_iot2_bg96_config.h"
+#include "em_eusart.h"
+#include "app_queue.h"
+#include
+#include "sl_iostream.h"
+
+at_platform_status_t status = NOT_INITIALIZED;
+ln_cb_t global_cb = 0;
+sl_sleeptimer_timer_handle_t my_timer;
+static uint8_t line_counter = 0;
+static uint8_t input_buffer[IN_BUFFER_SIZE];
+static uint16_t input_buffer_index = 0;
+
+static void timer_cb(sl_sleeptimer_timer_handle_t *handle, void *data);
+
+/**************************************************************************//**
+ * @brief
+ * CMU initialization.
+ *****************************************************************************/
+void initCMU(void)
+{
+ // Enable clock to GPIO and EUSART1
+ CMU_ClockEnable(cmuClock_GPIO, true);
+}
+
+/**************************************************************************//**
+ * @brief
+ * GPIO initialization.
+ *****************************************************************************/
+void initGPIO(void)
+{
+ CMU_ClockEnable(cmuClock_GPIO, true);
+ GPIO_PinModeSet(BG96_PWK_PORT,
+ BG96_PWK_PIN,
+ gpioModePushPull,
+ 0);
+
+ GPIO_PinModeSet(BG96_STA_PORT,
+ BG96_STA_PIN,
+ gpioModeInputPull,
+ 0);
+}
+
+/**************************************************************************//**
+ * @brief
+ * Initialization of platform driver.
+ *
+ * @param[in] line_callback
+ * Callback function for new line (and ">" character for special commands).
+ *
+ *****************************************************************************/
+void at_platform_init(ln_cb_t line_callback)
+{
+ global_cb = line_callback;
+ initCMU();
+ initGPIO();
+ status = READY;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Check ready status of platform driver.
+ *
+ *****************************************************************************/
+sl_status_t at_platform_check_device_ready(void)
+{
+ sl_status_t stt = SL_STATUS_INVALID_STATE;
+ switch (status) {
+ case NOT_INITIALIZED:
+ stt = SL_STATUS_NOT_INITIALIZED;
+ break;
+ case TRANSMIT:
+ stt = SL_STATUS_BUSY;
+ break;
+ case READY:
+ stt = SL_STATUS_OK;
+ break;
+ default:
+ stt = SL_STATUS_INVALID_STATE;
+ }
+ return stt;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Platform driver send command function.
+ * This function adds \r to the command string.
+ * Command string SHALL be allocated until command is sent.
+ * This function uses UART TX and RX interrupt.
+ *
+ * @param[in] cmd
+ * Pointer to the command to send.
+ *
+ * @param[in] timeout_ms
+ * Timeout for the command in milliseconds.
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_ALLOCATION_FAILED if cmd == NULL.
+ *****************************************************************************/
+sl_status_t at_platform_send_cmd(volatile uint8_t *cmd,
+ volatile uint16_t timeout_ms)
+{
+ sl_status_t st;
+
+ if (NULL != cmd) {
+ size_t cmd_length = sl_strlen((char *) cmd);
+ if (cmd_length < CMD_MAX_SIZE - 1) {
+ sl_strcat_s((char *) cmd, CMD_MAX_SIZE, "\r");
+ sl_iostream_write(sl_iostream_bg96_handle, (const void *)cmd,
+ sl_strlen((char *) cmd));
+
+ line_counter = 0;
+ status = TRANSMIT;
+ st = sl_sleeptimer_restart_timer_ms(&my_timer, timeout_ms, timer_cb,
+ (void *) NULL, 0, 0);
+ return st;
+ }
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Platform driver finish function.
+ * Used to end ongoing communication.
+ * Stops timeout and hardware interrupts.
+ *
+ *****************************************************************************/
+void at_platform_finish_cmd(void)
+{
+ status = READY;
+ sl_sleeptimer_stop_timer(&my_timer);
+}
+
+/**************************************************************************//**
+ * @brief
+ * Platform driver process function.
+ * Used to process incoming uart rx data
+ *
+ *****************************************************************************/
+void at_platform_process(void)
+{
+ static uint8_t tempdata;
+
+ while (SL_STATUS_OK == sl_iostream_getchar(sl_iostream_bg96_handle,
+ ( char *)&tempdata)) {
+ input_buffer[input_buffer_index] = tempdata;
+
+ if (input_buffer_index == 0) {
+ if ((input_buffer[0] == '\r') || (input_buffer[0] == '\n')) {
+ input_buffer[0] = 0;
+ } else {
+ input_buffer_index++;
+ }
+ } else if (input_buffer_index == 1) {
+ if ((input_buffer[1] == ' ') && (input_buffer[0] == '>')) {
+ global_cb(input_buffer, ++line_counter);
+ memset(input_buffer, 0, IN_BUFFER_SIZE);
+ input_buffer_index = 0;
+ } else {
+ input_buffer_index++;
+ }
+ } else {
+ if (input_buffer[input_buffer_index] == '\r') {
+ input_buffer[input_buffer_index] = 0;
+ global_cb(input_buffer, ++line_counter);
+ memset((void *) input_buffer, 0, IN_BUFFER_SIZE);
+ input_buffer_index = 0;
+ } else if (input_buffer_index < (IN_BUFFER_SIZE - 1)) {
+ input_buffer_index++;
+ } else {
+ global_cb(input_buffer, ++line_counter);
+ memset(input_buffer, 0, IN_BUFFER_SIZE);
+ input_buffer_index = 0;
+ }
+ }
+ }
+}
+
+/**************************************************************************//**
+ * @brief
+ * Timeout handler function.
+ *
+ * @param[in] handle
+ * Timer handler which called the callback function.
+ *
+ * @param [in] data
+ * Timer data sent by the caller of callback function.
+ *
+ *****************************************************************************/
+static void timer_cb(sl_sleeptimer_timer_handle_t *handle,
+ void *data)
+{
+ (void) (data);
+ (void) handle;
+ status = READY;
+ if (NULL != global_cb) {
+ global_cb(NULL, 0);
+ }
+}
diff --git a/driver/public/mikroe/lte_iot2_bg96/src/mikroe_bg96.c b/driver/public/mikroe/lte_iot2_bg96/src/mikroe_bg96.c
new file mode 100644
index 00000000..6ee8970b
--- /dev/null
+++ b/driver/public/mikroe/lte_iot2_bg96/src/mikroe_bg96.c
@@ -0,0 +1,1230 @@
+/***************************************************************************//**
+ * @file mikroe_bg96.c
+ * @brief mikroe_bg96.c
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#include "mikroe_bg96.h"
+#include "mikroe_lte_iot2_bg96_config.h"
+#include "em_gpio.h"
+#include "sl_sleeptimer.h"
+#include "at_parser_core.h"
+#include "at_parser_utility.h"
+#include
+
+#define BITMASK_7BITS 0x7F
+#define BITMASK_8BITS 0xFF
+#define BITMASK_HIGH_4BITS 0xF0
+#define BITMASK_LOW_4BITS 0x0F
+#define TYPE_OF_ADDRESS_INTERNATIONAL_PHONE 0x91
+#define SMS_MAX_7BIT_TEXT_LENGTH 160
+#define SMS_MAX_PDU_LENGTH 256
+#define SMS_DELIVER_ONE_MESSAGE 0x04
+#define SMS_SUBMIT 0x11
+
+static const char digits[] =
+{
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+static enum {
+ bg96_ready = 0, bg96_wait_for_gpio, bg96_wait_for_device,
+} bg96_state;
+
+static bool required_state = false;
+static at_scheduler_status_t *global_output;
+
+static sl_sleeptimer_timer_handle_t bg96_timer_gpio_handle;
+static sl_sleeptimer_timer_handle_t bg96_timer_process_handler;
+static void bg96_timer_gpio_callback(sl_sleeptimer_timer_handle_t *handle,
+ void *data);
+static void bg96_timer_process_callback(sl_sleeptimer_timer_handle_t *handle,
+ void *data);
+
+static uint32_t pdu_encode(uint8_t *service_center_number,
+ uint8_t *phone_number,
+ uint8_t *sms_text,
+ uint8_t *output_buffer,
+ uint16_t buffer_size);
+
+static uint32_t encode_pdu_message(uint8_t *sms_text,
+ int16_t sms_text_length,
+ uint8_t *output_buffer,
+ uint16_t buffer_size);
+static uint32_t encode_phone_number (uint8_t *phone_number,
+ uint8_t *output_buffer,
+ uint16_t buffer_size);
+
+static void str_cut_chr (uint8_t *str, uint8_t chr);
+static void uint8_to_hex(uint8_t input, uint8_t *output);
+static void uint8_to_str(uint8_t input, uint8_t *output);
+
+/**************************************************************************//**
+ * @brief
+ * BG96 module initialize function.
+ *
+ *****************************************************************************/
+void bg96_init(void)
+{
+ at_parser_init();
+ sl_sleeptimer_start_periodic_timer_ms(&bg96_timer_process_handler,
+ 200,
+ bg96_timer_process_callback,
+ NULL,
+ 0,
+ 0);
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 is alive status getter function.
+ *
+ *****************************************************************************/
+bool bg96_is_alive(void)
+{
+ return (bool) GPIO_PinInGet(BG96_STA_PORT, BG96_STA_PIN);
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 module sleep function.
+ *
+ * @return
+ * SL_STATUS_OK if sleep initialization was successful.
+ * SL_STATUS_BUSY if sleep/wake up sequence has been already started.
+ * SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG timer error.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_sleep(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t timer_status;
+
+ if (bg96_ready == bg96_state) {
+ if (bg96_is_alive()) {
+ if (NULL == output_object) {
+ return SL_STATUS_ALLOCATION_FAILED;
+ }
+
+ global_output = output_object;
+ GPIO_PinOutSet(BG96_PWK_PORT, BG96_PWK_PIN);
+ timer_status = sl_sleeptimer_restart_timer_ms(&bg96_timer_gpio_handle,
+ BG96_GPIO_H_TIME,
+ bg96_timer_gpio_callback,
+ (void *) NULL,
+ 0,
+ 0);
+
+ if (SL_STATUS_OK == timer_status) {
+ required_state = false;
+ bg96_state = bg96_wait_for_gpio;
+ output_object->status = SL_STATUS_BUSY;
+ output_object->error_code = 0;
+ return SL_STATUS_OK;
+ } else {
+ return timer_status;
+ }
+ } else {
+ // device is already sleeping
+ output_object->status = SL_STATUS_OK;
+ output_object->error_code = 0;
+ }
+ return SL_STATUS_OK;
+ } else {
+ return SL_STATUS_BUSY;
+ }
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 module wake up function.
+ *
+ * @return
+ * SL_STATUS_OK if wake-up initialization was successful.
+ * SL_STATUS_BUSY if sleep/wake up sequence has been already started.
+ * SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG timer error.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_wake_up(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ if (bg96_ready == bg96_state) {
+ if (!bg96_is_alive()) {
+ global_output = output_object;
+ GPIO_PinOutSet(BG96_PWK_PORT, BG96_PWK_PIN);
+ sl_status_t timer_status = sl_sleeptimer_restart_timer_ms(
+ &bg96_timer_gpio_handle,
+ BG96_GPIO_H_TIME,
+ bg96_timer_gpio_callback,
+ (void *) NULL,
+ 0,
+ 0);
+
+ if (SL_STATUS_OK == timer_status) {
+ required_state = true;
+ bg96_state = bg96_wait_for_gpio;
+ output_object->status = SL_STATUS_BUSY;
+ output_object->error_code = 0;
+ return SL_STATUS_OK;
+ } else {
+ return timer_status;
+ }
+ } else {
+ // device is already wakeup
+ output_object->status = SL_STATUS_OK;
+ output_object->error_code = 0;
+ }
+
+ return SL_STATUS_OK;
+ } else {
+ return SL_STATUS_BUSY;
+ }
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Initialization of GNSS function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_gnss_start(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_qgps = { "AT+QGPS=1", at_gps_start_stop_cb,
+ AT_DEFAULT_TIMEOUT };
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_qgps));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Get the GNSS location string.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_gnss_get_position(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_gpsloc = { "AT+QGPSLOC?", at_gpsloc_cb,
+ AT_DEFAULT_TIMEOUT };
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_gpsloc));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return SL_STATUS_OK;
+ }
+
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Stop GNSS function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_gnss_stop(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_imei = { "AT+QGPSEND", at_gps_start_stop_cb,
+ AT_DEFAULT_TIMEOUT };
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_imei));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return SL_STATUS_OK;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT initialization.
+ *
+ *****************************************************************************/
+void bg96_nb_init(void)
+{
+ bg96_init();
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT open a TCP or UDP connection.
+ *
+ * @param[in] connection
+ * Pointer to the connection descriptor structure.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL or connection ==
+ * NULL.
+ *****************************************************************************/
+sl_status_t bg96_nb_open_connection(bg96_nb_connection_t *connection,
+ at_scheduler_status_t *output_object)
+{
+ if ((NULL != output_object) && (NULL != connection)) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ // format example:
+ // "AT+QIOPEN=1,0,\"TCP\",\"cloudsocket.hologram.io\",9999,0,1"
+ uint8_t conn_string[50];
+ uint8_t base_cmd[] = "AT+QIOPEN=1,";
+ static at_cmd_desc_t at_open = { "", at_open_cb, AT_OPEN_TIMEOUT };
+ static at_cmd_desc_t at_qstate = { "AT+QISTATE=0,1", at_qistate_cb,
+ AT_DEFAULT_TIMEOUT };
+
+ at_parser_clear_cmd(&at_open);
+ validate(cmd_status,
+ at_parser_extend_cmd(&at_open, base_cmd));
+ if (!strncmp((const char *) connection->port_type, "TCP", 15)
+ || !strncmp((const char *) connection->port_type, "UDP", 15)) {
+ snprintf((char *) conn_string, 50, "%d,\"%s\",\"%s\",%d,0,1",
+ (int) connection->socket, (const char *) connection->port_type,
+ (const char *) connection->address, (int) connection->port);
+ validate(cmd_status, at_parser_extend_cmd(&at_open, conn_string));
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_open));
+ } else if (!strncmp((const char *) connection->port_type, "TCP LISTENER",
+ 15)
+ || !strncmp((const char *) connection->port_type,
+ "UDP LISTENER", 15)) {
+ snprintf((char *) conn_string, 50, "%d,\"%s\",\"%s\",0,%d,0",
+ (int) connection->socket, (const char *) connection->port_type,
+ (const char *) connection->address, (int) connection->port);
+ validate(cmd_status, at_parser_extend_cmd(&at_open, conn_string));
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_open));
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_qstate));
+ } else {
+ return SL_STATUS_FAIL;
+ }
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT network registration.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_network_registration(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_cmds[] = { { "AT+CFUN=0", at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT },
+ {
+ "AT+QCFG=\"nbsibscramble\",0",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ {
+ "AT+QCFG=\"nwscanmode\",0,1",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ {
+ "AT+QCFG=\"roamservice\",2,1",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ {
+ "AT+QCFG=\"nwscanseq\",020103,1",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ {
+ "AT+QCFG=\"band\",0,0,80,1",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ {
+ "AT+QCFG=\"iotopmode\",1,1",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ {
+ "AT+QCFG=\"servicedomain\",1,1",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ {
+ "AT+CGDCONT=1,\"IP\",\"hologram\"",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ { "AT+CFUN=1", at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT },
+ {
+ "AT+COPS?",
+ at_cops_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ {
+ "AT+CREG=1;+CGREG=1;+CEREG=1",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ {
+ "AT+COPS=0",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ },
+ {
+ "AT+QICSGP=1,1,\"hologram\",\"\",\"\",1",
+ at_ok_error_cb,
+ AT_DEFAULT_TIMEOUT
+ }, };
+
+ uint8_t at_cmd_size = sizeof(at_cmds) / sizeof(at_cmd_desc_t);
+ uint8_t i;
+
+ for (i = 0; i < at_cmd_size; i++) {
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_cmds[i]));
+ }
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT close client connection.
+ *
+ * @param[in] connection
+ * Pointer to the connection descriptor structure.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL or connection ==
+ * NULL.
+ *****************************************************************************/
+sl_status_t bg96_nb_close_connection(bg96_nb_connection_t *connection,
+ at_scheduler_status_t *output_object)
+{
+ if ((NULL != output_object) && (NULL != connection)) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ uint8_t conn_string[5];
+ uint8_t base_cmd[] = "AT+QICLOSE=";
+ static at_cmd_desc_t at_close = { "", at_ok_error_cb, AT_OPEN_TIMEOUT };
+
+ snprintf((char *) conn_string, 5, "%d", (int) connection->socket);
+
+ at_parser_clear_cmd(&at_close);
+ validate(cmd_status, at_parser_extend_cmd(&at_close, base_cmd));
+ validate(cmd_status, at_parser_extend_cmd(&at_close, conn_string));
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_close));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB send data function.
+ *
+ * @param[in] connection
+ * Pointer to the connection descriptor structure.
+ *
+ * @param[in] data
+ * Pointer to the data to send.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL or data == NULL or
+ * connection == NULL.
+ *****************************************************************************/
+sl_status_t bg96_nb_send_data(bg96_nb_connection_t *connection,
+ uint8_t *data,
+ at_scheduler_status_t *output_object)
+{
+ if ((NULL != output_object) && (NULL != data) && (NULL != connection)) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ uint8_t data_l_string[10];
+ uint8_t base_cmd[] = "AT+QISEND=";
+ static at_cmd_desc_t at_qisend = { "", at_send_cb, AT_DEFAULT_TIMEOUT };
+ static at_cmd_desc_t at_data = { "", at_data_cb, AT_SEND_TIMEOUT };
+
+ at_parser_clear_cmd(&at_qisend);
+ at_parser_clear_cmd(&at_data);
+ validate(cmd_status, at_parser_extend_cmd(&at_qisend, base_cmd));
+ validate(cmd_status, at_parser_extend_cmd(&at_data, data));
+
+ size_t data_length = sl_strlen((char *) at_data.cms_string);
+ if (data_length < DATA_MAX_LENGTH) {
+ snprintf((char *) data_l_string, 10, "%d,%d", (int) connection->socket,
+ (int) data_length);
+ validate(cmd_status, at_parser_extend_cmd(&at_qisend, data_l_string));
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_qisend));
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_data));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT receive data function.
+ *
+ * @param[in] connection
+ * Pointer to the connection descriptor structure.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_nb_receive_data(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_qird = { "AT+QIRD=11,100", at_recv_cb,
+ AT_DEFAULT_TIMEOUT };
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_qird));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT read actual IP address function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_read_ip(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_ip = { "AT+QIACT?", at_ip_cb, AT_DEFAULT_TIMEOUT };
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_ip));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT get actual operator function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_get_operator(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_cops =
+ { "AT+COPS?", at_cops_cb, AT_DEFAULT_TIMEOUT };
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_cops));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT read HW IMEI number.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_read_imei(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_imei = { "AT+GSN", at_imei_cb, AT_DEFAULT_TIMEOUT };
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_imei));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 module get information function.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_read_infor(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_infor = { "ATI", at_infor_cb, AT_DEFAULT_TIMEOUT };
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_infor));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT set TE character set as GSM.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data..
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_set_te_gsm(at_scheduler_status_t *output_object)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_te_gsm = { "AT+CSCS=\"GSM\"", at_te_gsm_cb,
+ AT_DEFAULT_TIMEOUT };
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_te_gsm));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT Configure the service domain of UE.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @param[in] type
+ * Variable to set type of the service domain
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_config_service_domain(at_scheduler_status_t *output_object,
+ config_service_domain_type_t type)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_config_service_domain = {
+ "", at_service_domain_cb, AT_DEFAULT_TIMEOUT
+ };
+
+ at_parser_clear_cmd(&at_config_service_domain);
+
+ if (type == service_domain_type_PSOnly_e) {
+ sl_strcpy_s((char *)at_config_service_domain.cms_string,
+ CMD_MAX_SIZE,
+ (const char * )"AT+QCFG=\"servicedomain\",1,1");
+ } else if (type == service_domain_type_CS_and_PS_e) {
+ sl_strcpy_s((char *)at_config_service_domain.cms_string,
+ CMD_MAX_SIZE,
+ (const char * )"AT+QCFG=\"servicedomain\",2,1");
+ }
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_config_service_domain));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT set SMS mode
+ *
+ * @param[in] mode
+ * Variable to set sms mode
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL.
+ *****************************************************************************/
+sl_status_t bg96_set_sms_mode(at_scheduler_status_t *output_object,
+ set_sms_mode_t mode)
+{
+ if (NULL != output_object) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_set_sms_mode = {
+ "", set_sms_mode_cb, AT_DEFAULT_TIMEOUT
+ };
+
+ at_parser_clear_cmd(&at_set_sms_mode);
+
+ if (mode == set_sms_mode_pdu) {
+ sl_strcpy_s((char *)at_set_sms_mode.cms_string, CMD_MAX_SIZE,
+ (const char * )"AT+CMGF=0");
+ } else if (mode == set_sms_mode_text) {
+ sl_strcpy_s((char *)at_set_sms_mode.cms_string, CMD_MAX_SIZE,
+ (const char * )"AT+CMGF=1");
+ }
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_set_sms_mode));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+ return cmd_status;
+ }
+
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT send SMS Text
+ *
+ * @param[in] sms_text_object
+ * Pointer to the sms text descriptor structure.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL or sms_text_object
+ * == NULL.
+ *****************************************************************************/
+sl_status_t bg96_send_sms_text(at_scheduler_status_t *output_object,
+ bg96_sms_text_t *sms_text_object)
+{
+ if ((NULL != output_object) && (NULL != sms_text_object)) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ uint8_t base_cmd[] = "AT+CMGS=";
+ static at_cmd_desc_t at_sms_cmd = {
+ "", at_sms_send_command_cb, AT_DEFAULT_TIMEOUT
+ };
+ static at_cmd_desc_t at_sms_data = {
+ "", at_sms_send_data_cb, AT_SMS_TEXT_TIMEOUT
+ };
+
+ at_parser_clear_cmd(&at_sms_cmd);
+ at_parser_clear_cmd(&at_sms_data);
+
+ validate(cmd_status,
+ at_parser_extend_cmd(&at_sms_cmd, (uint8_t *)base_cmd));
+ validate(cmd_status, at_parser_extend_cmd(&at_sms_cmd, (uint8_t *)"\""));
+ validate(cmd_status, at_parser_extend_cmd(&at_sms_cmd,
+ sms_text_object->phone_number));
+ validate(cmd_status, at_parser_extend_cmd(&at_sms_cmd, (uint8_t *)"\""));
+
+ validate(cmd_status, at_parser_extend_cmd(&at_sms_data,
+ sms_text_object->sms_text_content));
+ validate(cmd_status, at_parser_extend_cmd(&at_sms_data, (uint8_t *)"\032"));
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_sms_cmd));
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_sms_data));
+
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT send SMS PDU
+ *
+ * @param[in] sms_pdu_object
+ * Pointer to the sms pdu descriptor structure.
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL or sms_pdu_object
+ * == NULL.
+ *****************************************************************************/
+sl_status_t bg96_send_sms_pdu(at_scheduler_status_t *output_object,
+ bg96_sms_pdu_t *sms_pdu_object)
+{
+ if ((NULL != output_object) && (NULL != sms_pdu_object)) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ uint8_t smsc[32] = { 0 };
+ uint8_t phone_num[32] = { 0 };
+ uint8_t byte_buf[4] = { 0 };
+ uint8_t pdu_buf[SMS_MAX_PDU_LENGTH] = { 0 };
+
+ uint8_t base_cmd[] = "AT+CMGS=";
+ static at_cmd_desc_t at_sms_cmd = { "",
+ at_sms_send_command_cb,
+ AT_DEFAULT_TIMEOUT };
+ static at_cmd_desc_t at_sms_data = {
+ "", at_sms_send_data_cb, AT_SMS_TEXT_TIMEOUT
+ };
+ at_parser_clear_cmd(&at_sms_cmd);
+ at_parser_clear_cmd(&at_sms_data);
+
+ sl_strcpy_s((char *) smsc,
+ 32,
+ (const char *) sms_pdu_object->service_center_number);
+ sl_strcpy_s((char *) phone_num,
+ 32,
+ (const char *) sms_pdu_object->phone_number);
+ str_cut_chr(smsc, '+');
+ str_cut_chr(phone_num, '+');
+
+ int16_t pdu_buf_len = pdu_encode(smsc,
+ phone_num,
+ sms_pdu_object->sms_text_content,
+ pdu_buf,
+ SMS_MAX_PDU_LENGTH);
+
+ if (pdu_buf_len < 0) {
+ return SL_STATUS_FAIL;
+ }
+
+ uint8_t length = pdu_buf_len - ((sl_strlen((char *) smsc) - 1) / 2 + 3);
+ uint8_to_str(length, byte_buf);
+ str_cut_chr(byte_buf, ' ');
+ validate(cmd_status,
+ at_parser_extend_cmd(&at_sms_cmd, (uint8_t *)base_cmd));
+ validate(cmd_status,
+ at_parser_extend_cmd(&at_sms_cmd, (uint8_t *)byte_buf));
+
+ for ( int16_t cnt = 0; cnt < pdu_buf_len; cnt++ )
+ {
+ uint8_to_hex(pdu_buf[cnt], byte_buf);
+ validate(cmd_status, at_parser_extend_cmd(&at_sms_data, byte_buf));
+ }
+
+ validate(cmd_status, at_parser_extend_cmd(&at_sms_data, (uint8_t *)"\032"));
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_sms_cmd));
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_sms_data));
+
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+
+ return cmd_status;
+ }
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+/**************************************************************************//**
+ * @brief
+ * BG96 NB IoT set SIM APN
+ *
+ * @param[in] sim_apn
+ * Pointer to the SIM APN descriptor .
+ *
+ * @param[out] output_object
+ * Pointer to the output object which contains the command status and
+ * output data.
+ *
+ * @return
+ * SL_STATUS_OK if command successfully added to the command queue.
+ * SL_STATUS_FAIL if scheduler is busy or command queue is full.
+ * SL_STATUS_INVALID_PARAMETER if output_object == NULL or sim_apn == NULL
+ *****************************************************************************/
+sl_status_t bg96_set_sim_apn(at_scheduler_status_t *output_object,
+ uint8_t *sim_apn)
+{
+ if ((NULL != output_object) && (NULL != sim_apn)) {
+ sl_status_t cmd_status = SL_STATUS_OK;
+ static at_cmd_desc_t at_set_apn = {
+ "AT+CGDCONT=1,\"IP\",\"", at_set_sim_apn_cb, AT_DEFAULT_TIMEOUT
+ };
+
+ validate(cmd_status, at_parser_extend_cmd(&at_set_apn, (uint8_t *)sim_apn));
+ validate(cmd_status, at_parser_extend_cmd(&at_set_apn, (uint8_t *)"\""));
+
+ validate(cmd_status, at_parser_add_cmd_to_q(&at_set_apn));
+ validate(cmd_status, at_parser_start_scheduler(output_object));
+
+ return cmd_status;
+ }
+
+ return SL_STATUS_INVALID_PARAMETER;
+}
+
+static uint32_t pdu_encode(uint8_t *service_center_number,
+ uint8_t *phone_number,
+ uint8_t *sms_text,
+ uint8_t *output_buffer,
+ uint16_t buffer_size)
+{
+ int16_t output_buffer_length = 0;
+
+ if ((NULL != service_center_number) && (NULL != phone_number)
+ && (NULL != sms_text) && (NULL != output_buffer)) {
+ if (buffer_size < 2) {
+ return SL_STATUS_FAIL;
+ }
+
+ // 1. Set SMS center number.
+ int16_t length = 0;
+ if ((service_center_number != 0)
+ && (sl_strlen((char *) service_center_number) > 0)) {
+ // Add type of address.
+ output_buffer[1] = TYPE_OF_ADDRESS_INTERNATIONAL_PHONE;
+ length = encode_phone_number(service_center_number,
+ output_buffer + 2,
+ buffer_size - 2);
+ if ((length < 0) && (length >= 254)) {
+ return SL_STATUS_FAIL;
+ }
+ length++;
+ }
+ output_buffer[0] = length;
+ output_buffer_length = length + 1;
+ if (output_buffer_length + 4 > buffer_size) {
+ return SL_STATUS_FAIL; // Check if it has space for four more bytes.
+ }
+
+ // 2. Set type of message.
+ output_buffer[output_buffer_length++] = SMS_SUBMIT;
+ output_buffer[output_buffer_length++] = 0x00; // Message reference.
+
+ // 3. Set phone number.
+ output_buffer[output_buffer_length] = sl_strlen((char *) phone_number);
+ output_buffer[output_buffer_length
+ + 1] = TYPE_OF_ADDRESS_INTERNATIONAL_PHONE;
+ length = encode_phone_number(phone_number,
+ output_buffer + output_buffer_length + 2,
+ buffer_size - output_buffer_length - 2);
+ output_buffer_length += length + 2;
+ if (output_buffer_length + 4 > buffer_size) {
+ return SL_STATUS_FAIL; // Check if it has space for four more bytes.
+ }
+
+ // 4. Protocol identifiers.
+ output_buffer[output_buffer_length++] = 0x00; // TP-PID: Protocol
+ // identifier.
+ output_buffer[output_buffer_length++] = 0x00; // TP-DCS: Data coding
+ // scheme.
+ output_buffer[output_buffer_length++] = 0xB0; // TP-VP: Validity: 10
+ // days
+
+ // 5. SMS message.
+ int16_t sms_text_length = sl_strlen((char *) sms_text);
+ if (sms_text_length > SMS_MAX_7BIT_TEXT_LENGTH) {
+ return SL_STATUS_FAIL;
+ }
+ output_buffer[output_buffer_length++] = sms_text_length;
+
+ length = encode_pdu_message(sms_text,
+ sms_text_length,
+ output_buffer + output_buffer_length,
+ buffer_size - output_buffer_length);
+ if (length < 0) {
+ return SL_STATUS_FAIL;
+ }
+ output_buffer_length += length;
+ }
+
+ return output_buffer_length;
+}
+
+static uint32_t encode_pdu_message(uint8_t *sms_text, int16_t sms_text_length,
+ uint8_t *output_buffer, uint16_t buffer_size)
+{
+ int16_t output_buffer_length = 0;
+
+ if ((NULL != sms_text) && (NULL != output_buffer)) {
+ // Check if output buffer is big enough.
+ if ((sms_text_length * 7 + 7) / 8 > buffer_size) {
+ return SL_STATUS_FAIL;
+ }
+
+ int16_t carry_on_bits = 1;
+ int16_t i = 0;
+
+ for ( ; i < sms_text_length - 1; ++i )
+ {
+ output_buffer[output_buffer_length++] =
+ ((sms_text[i] & BITMASK_7BITS) >> (carry_on_bits - 1))
+ | ((sms_text[i + 1] & BITMASK_7BITS) << (8 - carry_on_bits));
+ carry_on_bits++;
+ if (carry_on_bits == 8) {
+ carry_on_bits = 1;
+ ++i;
+ }
+ }
+
+ if (i < sms_text_length) {
+ output_buffer[output_buffer_length++] = (sms_text[i] & BITMASK_7BITS) >>
+ (carry_on_bits - 1);
+ }
+ }
+
+ return output_buffer_length;
+}
+
+static uint32_t encode_phone_number(uint8_t *phone_number,
+ uint8_t *output_buffer,
+ uint16_t buffer_size)
+{
+ int16_t output_buffer_length = 0;
+
+ if ((NULL != phone_number) && (NULL != output_buffer)) {
+ int16_t phone_number_length = sl_strlen((char *) phone_number);
+
+ // Check if the output buffer is big enough.
+ if ((phone_number_length + 1) / 2 > buffer_size) {
+ return SL_STATUS_FAIL;
+ }
+
+ int16_t i = 0;
+ for ( ; i < phone_number_length; ++i )
+ {
+ if ((phone_number[i] < '0') && (phone_number[i] > '9')) {
+ return SL_STATUS_FAIL;
+ }
+
+ if (i % 2 == 0) {
+ output_buffer[output_buffer_length++] = BITMASK_HIGH_4BITS
+ | (phone_number[i] - '0');
+ } else {
+ output_buffer[output_buffer_length - 1] =
+ (output_buffer[output_buffer_length - 1] & BITMASK_LOW_4BITS)
+ | ((phone_number[i] - '0') << 4);
+ }
+ }
+ }
+ return output_buffer_length;
+}
+
+static void str_cut_chr(uint8_t *str, uint8_t chr)
+{
+ uint16_t cnt_0, cnt_1;
+ for ( cnt_0 = 0; cnt_0 < sl_strlen((char *) str); cnt_0++ )
+ {
+ if (str[cnt_0] == chr) {
+ for ( cnt_1 = cnt_0; cnt_1 < sl_strlen((char *) str); cnt_1++ )
+ {
+ str[cnt_1] = str[cnt_1 + 1];
+ }
+ }
+ }
+}
+
+static void uint8_to_hex(uint8_t input, uint8_t *output)
+{
+ if (NULL != output) {
+ output[0] = digits[input >> 4];
+ output[1] = digits[input & 0xF];
+ output[2] = 0;
+ }
+}
+
+static void uint8_to_str(uint8_t input, uint8_t *output)
+{
+ if (NULL != output) {
+ uint8_t digit_pos;
+
+ for ( digit_pos = 0; digit_pos < 3; digit_pos++ )
+ {
+ output[digit_pos] = ' ';
+ }
+
+ output[digit_pos--] = 0;
+
+ while (1)
+ {
+ output[digit_pos] = (input % 10u) + 48;
+ input = input / 10u;
+ if (digit_pos == 0) {
+ break;
+ }
+
+ digit_pos--;
+ }
+ }
+}
+
+/**************************************************************************//**
+ * @brief
+ * Local callback function for bg96 timer.
+ *
+ *****************************************************************************/
+static void bg96_timer_gpio_callback(sl_sleeptimer_timer_handle_t *handle,
+ void *data)
+{
+ (void) data;
+
+ if (handle == &bg96_timer_gpio_handle) {
+ switch (bg96_state) {
+ case bg96_wait_for_gpio:
+ GPIO_PinOutClear(BG96_PWK_PORT, BG96_PWK_PIN);
+ bg96_state = bg96_wait_for_device;
+
+ sl_sleeptimer_restart_timer_ms(&bg96_timer_gpio_handle,
+ BG96_TIMEOUT_MS,
+ bg96_timer_gpio_callback,
+ (void *) NULL,
+ 0,
+ 0);
+ break;
+ case bg96_wait_for_device:
+ if (global_output != NULL) {
+ global_output->error_code = SL_STATUS_TIMEOUT;
+ global_output->status = SL_STATUS_OK;
+ }
+ bg96_state = bg96_ready;
+ break;
+ default:
+ bg96_state = bg96_ready;
+ }
+ }
+}
+
+static void bg96_timer_process_callback(sl_sleeptimer_timer_handle_t *handle,
+ void *data)
+{
+ (void)data;
+
+ if (handle == &bg96_timer_process_handler) {
+ switch (bg96_state) {
+ case bg96_ready:
+ break;
+ case bg96_wait_for_gpio:
+ break;
+ case bg96_wait_for_device:
+ if (bg96_is_alive() == required_state) {
+ sl_sleeptimer_stop_timer(&bg96_timer_gpio_handle);
+
+ if (global_output != NULL) {
+ global_output->error_code = 0;
+ global_output->status = SL_STATUS_OK;
+ }
+ bg96_state = bg96_ready;
+ }
+ break;
+ }
+ }
+}
diff --git a/driver/public/mikroe/microsd/config/mikroe_microsd_config.h b/driver/public/mikroe/microsd/config/mikroe_microsd_config.h
new file mode 100644
index 00000000..341caef6
--- /dev/null
+++ b/driver/public/mikroe/microsd/config/mikroe_microsd_config.h
@@ -0,0 +1,76 @@
+/***************************************************************************//**
+ * @file mikroe_microsd_config.h
+ * @brief SCL microsd config file
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_MICROSD_CONFIG_H_
+#define MIKROE_MICROSD_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// <<< Use Configuration Wizard in Context Menu >>>
+// SDcard clock settings
+
+// Set slow clock for card initialization <100000-400000>
+//
+// Default: 200000
+#define MIKROE_MICROSD_MMC_SLOW_CLOCK 200000
+
+// Set fast clock for card
+//
+// If set to 0, the default bitrate of SPI is used
+// Default: 0
+#define MIKROE_MICROSD_MMC_FAST_CLOCK 0
+//
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// MIKROE_MICROSD_MMC_CD
+// $[GPIO_MIKROE_MICROSD_MMC_CD]
+#define MIKROE_MICROSD_MMC_CD_PORT gpioPortB
+#define MIKROE_MICROSD_MMC_CD_PIN 0
+// [GPIO_MIKROE_MICROSD_MMC_CD]$
+
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_MICROSD_CONFIG_H_ */
diff --git a/driver/public/mikroe/microsd/inc/sl_sdc_sd_card.h b/driver/public/mikroe/microsd/inc/sl_sdc_sd_card.h
new file mode 100644
index 00000000..f18b6d3d
--- /dev/null
+++ b/driver/public/mikroe/microsd/inc/sl_sdc_sd_card.h
@@ -0,0 +1,124 @@
+/***************************************************************************//**
+ * @file sl_sdc_sd_card.h
+ * @brief Storage Device Controls SD Card include file
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ ********************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#ifndef SL_SDC_SD_CARD_H
+#define SL_SDC_SD_CARD_H
+
+#include "stdint.h"
+
+#include "ff.h"
+#include "diskio.h"
+
+#include "sl_sdc_platform_spi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @brief Initialize SPI interface for SD Card.
+ *
+ * @return SL_STATUS_OK if successful. Error code otherwise.
+ ******************************************************************************/
+sl_status_t sd_card_spi_init(SPIDRV_Handle_t spi_handle);
+
+/***************************************************************************//**
+ * @brief Initialize a SD Card.
+ *
+ * @return Status of Disk Functions
+ ******************************************************************************/
+DSTATUS sd_card_disk_initialize(void);
+
+/***************************************************************************//**
+ * @brief Get SD Card Status.
+ *
+ * @return Status of Disk Functions
+ ******************************************************************************/
+DSTATUS sd_card_disk_status(void);
+
+/***************************************************************************//**
+ * @brief
+ * Read Sector(s) from SD Card.
+ *
+ * @param[out] buff
+ * Pointer to the Data buffer to be read
+ *
+ * @param[in] sector
+ * Start sector in LBA
+ *
+ * @param[in] count
+ * Number of sectors to read
+ *
+ * @return Status of Disk Functions
+ ******************************************************************************/
+dresult_t sd_card_disk_read(BYTE *buff, LBA_t sector, UINT count);
+
+/***************************************************************************//**
+ * @brief
+ * Write Sector(s) to SD Card.
+ *
+ * @param[in] buff
+ * Pointer to the Data buffer to be written
+ *
+ * @param[in] sector
+ * Start sector in LBA
+ *
+ * @param[in] count
+ * Number of sectors to write
+ *
+ * @return Status of Disk Functions
+ ******************************************************************************/
+dresult_t sd_card_disk_write(const BYTE *buff, LBA_t sector, UINT count);
+
+/***************************************************************************//**
+ * @brief
+ * Miscellaneous Functions.
+ * This function is called to control device specific features
+ * and miscellaneous functions other than generic read/write.
+ *
+ * @param[in] cmd
+ * Control code
+ *
+ * @param[in] buff
+ * Buffer to send/receive control data
+ *
+ * @return Status of Disk Functions
+ ******************************************************************************/
+dresult_t sd_card_disk_ioctl(BYTE cmd, void *buff);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SL_SDC_SD_CARD_H
diff --git a/driver/public/mikroe/microsd/src/sl_sdc_sd_card.c b/driver/public/mikroe/microsd/src/sl_sdc_sd_card.c
new file mode 100644
index 00000000..31d80f4f
--- /dev/null
+++ b/driver/public/mikroe/microsd/src/sl_sdc_sd_card.c
@@ -0,0 +1,738 @@
+/***************************************************************************//**
+ * @file sl_sdc_sd_card.c
+ * @brief Storage Device Controls SD Card
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ ********************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#include "sl_sdc_sd_card.h"
+#include "mikroe_microsd_config.h"
+
+// SPI bit rate controls
+// Set slow clock for card initialization (100k-400k)
+#define FCLK_SLOW() \
+ sdc_platform_set_bit_rate(sdc_spi_handle, MIKROE_MICROSD_MMC_SLOW_CLOCK)
+// Set fast clock for generic read/write
+#if MIKROE_MICROSD_MMC_FAST_CLOCK == 0
+#define FCLK_FAST() \
+ if (sdc_spi_handle) { \
+ sdc_platform_set_bit_rate(sdc_spi_handle, \
+ sdc_spi_handle->initData.bitRate); \
+ }
+#else
+#define FCLK_SLOW() sdc_platform_set_bit_rate(sdc_spi_handle, \
+ MIKROE_MICROSD_MMC_FAST_CLOCK)
+#endif
+
+// Socket controls
+// MMC CS = L
+#define CS_LOW() // CS controlled by the SPI driver
+// MMC CS = H
+#define CS_HIGH() // CS controlled by the SPI driver
+
+#if defined(MIKROE_MICROSD_MMC_CD_PORT) && defined(MIKROE_MICROSD_MMC_CD_PORT)
+// Card detected (yes:true, no:false, default:true)
+#define MMC_CD (!GPIO_PinInGet(MIKROE_MICROSD_MMC_CD_PORT, \
+ MIKROE_MICROSD_MMC_CD_PIN))
+#endif
+
+// Definitions for MMC/SDC command
+#define CMD0 (0) // GO_IDLE_STATE
+#define CMD1 (1) // SEND_OP_COND (MMC)
+#define ACMD41 (0x80 + 41) // SEND_OP_COND (SDC)
+#define CMD8 (8) // SEND_IF_COND
+#define CMD9 (9) // SEND_CSD
+#define CMD10 (10) // SEND_CID
+#define CMD12 (12) // STOP_TRANSMISSION
+#define ACMD13 (0x80 + 13) // SD_STATUS (SDC)
+#define CMD16 (16) // SET_BLOCKLEN
+#define CMD17 (17) // READ_SINGLE_BLOCK
+#define CMD18 (18) // READ_MULTIPLE_BLOCK
+#define CMD23 (23) // SET_BLOCK_COUNT (MMC)
+#define ACMD23 (0x80 + 23) // SET_WR_BLK_ERASE_COUNT (SDC)
+#define CMD24 (24) // WRITE_BLOCK
+#define CMD25 (25) // WRITE_MULTIPLE_BLOCK
+#define CMD32 (32) // ERASE_ER_BLK_START
+#define CMD33 (33) // ERASE_ER_BLK_END
+#define CMD38 (38) // ERASE
+#define CMD48 (48) // READ_EXTR_SINGLE
+#define CMD49 (49) // WRITE_EXTR_SINGLE
+#define CMD55 (55) // APP_CMD
+#define CMD58 (58) // READ_OCR
+
+static volatile DSTATUS sd_card_status = STA_NOINIT; // Disk status
+static BYTE sd_card_type; // Card type flags
+static volatile UINT sd_card_timer_1, sd_card_timer_2; // 1kHz decrement timer
+
+static SPIDRV_Handle_t sdc_spi_handle = NULL;
+static sl_sleeptimer_timer_handle_t disk_timerproc_timer_handle;
+static void disk_timerproc_timer_callback(sl_sleeptimer_timer_handle_t *handle,
+ void *data);
+
+static bool wait_ready(UINT wt);
+static void deselect (void);
+static bool select(void);
+static bool rcvr_datablock(BYTE *buff, UINT btr);
+
+#if FF_FS_READONLY == 0
+static bool xmit_datablock(const BYTE *buff, BYTE token);
+
+#endif
+static BYTE send_cmd(BYTE cmd, DWORD arg);
+
+/***************************************************************************//**
+ * @brief
+ * Wait for card ready.
+ *
+ * @param[in] wt
+ * Timeout [ms]
+ *
+ * @return 1:Ready, 0:Timeout
+ ******************************************************************************/
+static bool wait_ready(UINT wt)
+{
+ BYTE data;
+
+ sd_card_timer_2 = wt;
+ do {
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data);
+ // This loop takes a time. Insert rot_rdq() here for multitask envilonment.
+ } while (data != 0xff && sd_card_timer_2); // Wait for card goes ready or
+ // timeout
+
+ return (data == 0xff) ? 1 : 0;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Deselect card and release SPI.
+ *
+ ******************************************************************************/
+static void deselect(void)
+{
+ BYTE data;
+
+ CS_HIGH();
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data); // Dummy clock (force DO hi-z for
+ // multiple slave SPI)
+}
+
+/***************************************************************************//**
+ * @brief
+ * Select card and wait for ready.
+ *
+ * @return 1:OK, 0:Timeout
+ ******************************************************************************/
+static bool select(void)
+{
+ BYTE data;
+
+ CS_LOW();
+ // Dummy clock (force DO enabled)
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data);
+
+ if (wait_ready(500)) {
+ return 1; // Wait for card ready
+ }
+
+ deselect();
+ return 0; // Timeout
+}
+
+/***************************************************************************//**
+ * @brief
+ * Receive a data packet from MMC.
+ *
+ * @param[in] buff
+ * Pointer to Data buffer to store received data
+ *
+ * @param[in] btr
+ * Byte count (must be multiple of 4)
+ *
+ * @return 1:OK, 0:Failed
+ ******************************************************************************/
+static bool rcvr_datablock(BYTE *buff, UINT btr)
+{
+ BYTE token;
+
+ sd_card_timer_1 = 100;
+ do { // Wait for data packet in timeout of 100ms
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &token);
+ } while ((token == 0xff) && sd_card_timer_1);
+
+ // If not valid data token, return with error
+ if (token != 0xfe) {
+ return 0;
+ }
+
+ sdc_rcvr_spi_multi(sdc_spi_handle, buff, btr); // Receive the data block into
+ // buffer
+ // Discard 2 byte-CRC.
+ // Refer to http://elm-chan.org/docs/mmc/mmc_e.html#dataxfer for details"
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &token);
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &token);
+
+ return 1;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Send a data packet to MMC.
+ *
+ * @param[in] buff
+ * Pointer to 512 byte data block to be transmitted
+ *
+ * @param[in] token
+ * Data token
+ *
+ * @return 1:OK, 0:Failed
+ ******************************************************************************/
+#if FF_FS_READONLY == 0
+static bool xmit_datablock(const BYTE *buff, BYTE token)
+{
+ BYTE data;
+
+ if (!wait_ready(500)) {
+ return 0;
+ }
+
+ sdc_xchg_spi(sdc_spi_handle, token, &data); // Xmit a token
+ if (token != 0xfd) { // Not StopTran token
+ sdc_xmit_spi_multi(sdc_spi_handle, buff, 512); // Xmit the data block to the
+ // MMC
+ // Discard 2 byte-CRC.
+ // Refer to http://elm-chan.org/docs/mmc/mmc_e.html#dataxfer for details"
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data);
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data);
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data); // Receive a data response
+ // If not accepted, return with error
+ if ((data & 0x1F) != 0x05) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+#endif
+
+/***************************************************************************//**
+ * @brief
+ * Send a command packet to MMC.
+ *
+ * @param[in] cmd
+ * Command index
+ *
+ * @param[in] arg
+ * Argument
+ *
+ * @return Status of Disk Functions
+ ******************************************************************************/
+static BYTE send_cmd(BYTE cmd, DWORD arg)
+{
+ BYTE n, data;
+
+ // ACMD is the command sequense of CMD55-CMD
+ if (cmd & 0x80) {
+ cmd &= 0x7f;
+ data = send_cmd(CMD55, 0);
+ if (data > 1) {
+ return data;
+ }
+ }
+
+ // Select the card and wait for ready except to stop multiple block read
+ if (cmd != CMD12) {
+ deselect();
+ if (!select()) {
+ return 0xff;
+ }
+ }
+
+ // Send command packet
+ sdc_xchg_spi(sdc_spi_handle, 0x40 | cmd, &data); // Start + Command index
+ sdc_xchg_spi(sdc_spi_handle, ((BYTE)(arg >> 24)), &data); // Argument[31..24]
+ sdc_xchg_spi(sdc_spi_handle, ((BYTE)(arg >> 16)), &data); // Argument[23..16]
+ sdc_xchg_spi(sdc_spi_handle, ((BYTE)(arg >> 8)), &data); // Argument[15..8]
+ sdc_xchg_spi(sdc_spi_handle, (BYTE)(arg), &data); // Argument[7..0]
+
+ n = 0x01; // Dummy CRC + Stop
+ if (cmd == CMD0) {
+ n = 0x95; // Valid CRC for CMD0(0) + Stop
+ }
+ if (cmd == CMD8) {
+ n = 0x87; // Valid CRC for CMD8(0x1AA) + Stop
+ }
+ sdc_xchg_spi(sdc_spi_handle, n, &data);
+
+ // Receive command response
+ if (cmd == CMD12) {
+ // Skip a stuff byte on stop to read
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data);
+ }
+ n = 10; // Wait for a valid response in timeout of 10 attempts
+ do {
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data);
+ } while ((data & 0x80) && --n);
+
+ return data; // Return with the response value
+}
+
+/***************************************************************************//**
+ * Inidialize an SD Card.
+ ******************************************************************************/
+DSTATUS sd_card_disk_initialize(void)
+{
+ BYTE n, cmd, ty, ocr[4], data;
+
+ for (sd_card_timer_1 = 10; sd_card_timer_1;) { // Wait for 10ms
+ }
+ if (sd_card_status & STA_NODISK) {
+ return sd_card_status; // Is card existing in the soket?
+ }
+
+ FCLK_SLOW();
+ for (n = 10; n; n--) {
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data); // Send 80 dummy clocks
+ }
+
+ ty = 0;
+ if (send_cmd(CMD0, 0) == 1) { // Put the card SPI mode
+ sd_card_timer_1 = 1000; // Initialization timeout = 1 sec
+ if (send_cmd(CMD8, 0x1aa) == 1) { // Is the card SDv2?
+ for (n = 0; n < 4; n++) {
+ // Get 32 bit return value of R7 resp
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &ocr[n]);
+ }
+
+ // Is the card supports vcc of 2.7-3.6V?
+ if ((ocr[2] == 0x01) && (ocr[3] == 0xaa)) {
+ // Wait for end of initialization with ACMD41(HCS)
+ while (sd_card_timer_1 && send_cmd(ACMD41, 1UL << 30)) {
+ }
+
+ // Check CCS bit in the OCR
+ if (sd_card_timer_1 && (send_cmd(CMD58, 0) == 0)) {
+ for (n = 0; n < 4; n++) {
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &ocr[n]);
+ }
+ ty = (ocr[0] & 0x40) ? CT_SDC2 | CT_BLOCK : CT_SDC2; // Card id SDv2
+ }
+ }
+ } else { // Not SDv2 card
+ if (send_cmd(ACMD41, 0) <= 1) { // SDv1 or MMC?
+ ty = CT_SDC1;
+ cmd = ACMD41; // SDv1 (ACMD41(0))
+ } else {
+ ty = CT_MMC3;
+ cmd = CMD1; // MMCv3 (CMD1(0))
+ }
+
+ // Wait for end of initialization
+ while (sd_card_timer_1 && send_cmd(cmd, 0)) {
+ }
+
+ // Set block length: 512
+ if ((!sd_card_timer_1) || (send_cmd(CMD16, 512) != 0)) {
+ ty = 0;
+ }
+ }
+ }
+ sd_card_type = ty; // Card type
+ deselect();
+
+ if (ty) { // OK
+ FCLK_FAST(); // Set fast clock
+ sd_card_status &= ~STA_NOINIT; // Clear STA_NOINIT flag
+ } else { // Failed
+ sd_card_status = STA_NOINIT;
+ }
+
+ return sd_card_status;
+}
+
+/***************************************************************************//**
+ * Get SD Card Status.
+ ******************************************************************************/
+DSTATUS sd_card_disk_status(void)
+{
+ return sd_card_status;
+}
+
+/***************************************************************************//**
+ * Read Sector(s) from SD Card.
+ ******************************************************************************/
+dresult_t sd_card_disk_read(BYTE *buff, LBA_t sector, UINT count)
+{
+ DWORD sect = (DWORD)sector;
+
+ // Check parameter
+ if (!count) {
+ return RES_PARERR;
+ }
+
+ // Check if drive is ready
+ if (sd_card_status & STA_NOINIT) {
+ return RES_NOTRDY;
+ }
+
+ // LBA ot BA conversion (byte addressing cards)
+ if (!(sd_card_type & CT_BLOCK)) {
+ sect *= 512;
+ }
+
+ // Single block read
+ if (count == 1) {
+ if ((send_cmd(CMD17, sect) == 0) // READ_SINGLE_BLOCK
+ && rcvr_datablock(buff, 512)) {
+ count = 0;
+ }
+ } else { // Multiple block read
+ if (send_cmd(CMD18, sect) == 0) { // READ_MULTIPLE_BLOCK
+ do {
+ if (!rcvr_datablock(buff, 512)) {
+ break;
+ }
+ buff += 512;
+ } while (--count);
+ send_cmd(CMD12, 0); // STOP_TRANSMISSION
+ }
+ }
+ deselect();
+
+ return count ? RES_ERROR : RES_OK;
+}
+
+/***************************************************************************//**
+ * Write Sector(s) to SD Card.
+ ******************************************************************************/
+#if FF_FS_READONLY == 0
+dresult_t sd_card_disk_write(const BYTE *buff, LBA_t sector, UINT count)
+{
+ DWORD sect = (DWORD)sector;
+
+ if (sd_card_status & STA_NOINIT) { // Check drive status
+ return RES_NOTRDY;
+ }
+ if (sd_card_status & STA_PROTECT) { // Check write protect
+ return RES_WRPRT;
+ }
+
+ // LBA ==> BA conversion (byte addressing cards)
+ if (!(sd_card_type & CT_BLOCK)) {
+ sect *= 512;
+ }
+
+ if (count == 1) { // Single sector write
+ if ((send_cmd(CMD24, sect) == 0) // WRITE_BLOCK
+ && xmit_datablock(buff, 0xFE)) {
+ count = 0;
+ }
+ } else { // Multiple sector write
+ if (sd_card_type & CT_SDC) {
+ send_cmd(ACMD23, count); // Predefine number of sectors
+ }
+ if (send_cmd(CMD25, sect) == 0) { // WRITE_MULTIPLE_BLOCK
+ do {
+ if (!xmit_datablock(buff, 0xFC)) {
+ break;
+ }
+ buff += 512;
+ } while (--count);
+
+ if (!xmit_datablock(0, 0xFD)) { // STOP_TRAN token
+ count = 1;
+ }
+ }
+ }
+ deselect();
+
+ return count ? RES_ERROR : RES_OK;
+}
+
+#endif
+
+/***************************************************************************//**
+ * This function is called to control device specific features
+ * and miscellaneous functions other than generic read/write.
+ ******************************************************************************/
+dresult_t sd_card_disk_ioctl(BYTE cmd, void *buff)
+{
+ dresult_t res;
+ BYTE n;
+ BYTE csd[16];
+ BYTE *ptr = buff;
+ BYTE data;
+ DWORD csize;
+#ifdef FF_USE_TRIM
+ LBA_t *range;
+ DWORD st;
+ DWORD ed;
+#endif
+
+ if (sd_card_status & STA_NOINIT) {
+ return RES_NOTRDY;
+ }
+
+ res = RES_ERROR;
+ switch (cmd) {
+ // Make sure that no pending write process.
+ // Do not remove this or written sector might not left updated.
+ case CTRL_SYNC:
+ if (select()) {
+ res = RES_OK;
+ }
+ deselect();
+ break;
+
+ // Get number of sectors on the disk (DWORD)
+ case GET_SECTOR_COUNT:
+ if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
+ if ((csd[0] >> 6) == 1) { // SDC ver 2.00
+ csize = csd[9]
+ + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
+ *(LBA_t *)buff = csize << 10;
+ } else { // SDC ver 1.XX or MMC
+ n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
+ csize =
+ (csd[8] >>
+ 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
+ *(LBA_t *)buff = csize << (n - 9);
+ }
+ res = RES_OK;
+ }
+ deselect();
+ break;
+
+ // Get erase block size in unit of sector (DWORD)
+ case GET_BLOCK_SIZE:
+ if (sd_card_type & CT_SDC2) { // SDv2?
+ if (send_cmd(ACMD13, 0) == 0) { // Read SD status
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data);
+ if (rcvr_datablock(csd, 16)) {// Read partial block
+ for (n = 64 - 16; n; n--) {
+ // Purge trailing data
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data);
+ }
+ *(DWORD *)buff = 16UL << (csd[10] >> 4);
+ res = RES_OK;
+ }
+ }
+ } else { // SDv1 or MMCv3
+ if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { // Read CSD
+ if (sd_card_type & CT_SDC1) { // SDv1
+ *(DWORD *)buff =
+ (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) <<
+ ((csd[13] >> 6) - 1);
+ } else { // MMCv3
+ *(DWORD *)buff =
+ ((WORD)((csd[10] & 124) >>
+ 2) + 1)
+ * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
+ }
+ res = RES_OK;
+ }
+ }
+ deselect();
+ break;
+
+#ifdef FF_USE_TRIM
+ // Erase a block of sectors (used when _USE_TRIM in ffconf.h is 1)
+ case CTRL_TRIM:
+ // Check if the card is SDC
+ if (!(sd_card_type & CT_SDC)) {
+ break;
+ }
+ // Get CSD
+ if (sd_card_disk_ioctl(MMC_GET_CSD, csd)) {
+ break;
+ }
+ // Check if ERASE_BLK_EN = 1
+ if (!(csd[10] & 0x40)) {
+ break;
+ }
+ range = buff;
+ st = (DWORD)range[0];
+ ed = (DWORD)range[1]; // Load sector block
+ if (!(sd_card_type & CT_BLOCK)) {
+ st *= 512;
+ ed *= 512;
+ }
+ // Erase sector block
+ if ((send_cmd(CMD32, st) == 0)
+ && (send_cmd(CMD33, ed) == 0)
+ && (send_cmd(CMD38, 0) == 0)
+ && wait_ready(60000)) {
+ res = RES_OK; // FatFs does not check result of this command
+ }
+ break;
+#endif
+
+ // Following commands are never used by FatFs module
+ // Get card type flags (1 byte)
+ case MMC_GET_TYPE:
+ *ptr = sd_card_type;
+ res = RES_OK;
+ break;
+
+ // Receive CSD as a data block (16 bytes)
+ case MMC_GET_CSD:
+ // READ_CSD
+ if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(ptr, 16)) {
+ res = RES_OK;
+ }
+ deselect();
+ break;
+
+ // Receive CID as a data block (16 bytes)
+ case MMC_GET_CID:
+ // READ_CID
+ if ((send_cmd(CMD10, 0) == 0) && rcvr_datablock(ptr, 16)) {
+ res = RES_OK;
+ }
+ deselect();
+ break;
+
+ // Receive OCR as an R3 resp (4 bytes)
+ case MMC_GET_OCR:
+ // READ_OCR
+ if (send_cmd(CMD58, 0) == 0) {
+ for (n = 4; n; n--) {
+ *ptr++ = sdc_xchg_spi(sdc_spi_handle, 0xff, &data);
+ }
+ res = RES_OK;
+ }
+ deselect();
+ break;
+
+ // Receive SD status as a data block (64 bytes)
+ case MMC_GET_SDSTAT:
+ // SD_STATUS
+ if (send_cmd(ACMD13, 0) == 0) {
+ sdc_xchg_spi(sdc_spi_handle, 0xff, &data);
+ if (rcvr_datablock(ptr, 64)) {
+ res = RES_OK;
+ }
+ }
+ deselect();
+ break;
+
+ default:
+ res = RES_PARERR;
+ break;
+ }
+
+ return res;
+}
+
+/***************************************************************************//**
+ * @brief Initialize SPI interface for SD Card.
+ ******************************************************************************/
+sl_status_t sd_card_spi_init(SPIDRV_Handle_t spi_handle)
+{
+ bool timer_is_running = false;
+
+ sdc_spi_handle = spi_handle;
+
+#if defined(MIKROE_MICROSD_MMC_CD_PORT) && defined(MIKROE_MICROSD_MMC_CD_PORT)
+ GPIO_PinModeSet(MIKROE_MICROSD_MMC_CD_PORT,
+ MIKROE_MICROSD_MMC_CD_PIN,
+ gpioModeInputPull,
+ 1);
+#endif
+
+ // MISO pin is not pulled-up by SDcard click board side with a resistor.
+ // This pin should be reconfigured in gpioModeInputPull mode.
+ GPIO_PinModeSet(spi_handle->initData.portRx,
+ spi_handle->initData.pinRx,
+ gpioModeInputPull,
+ 1);
+
+ // Make sure the disk_timerproc_timer_handle timer is initialized only once
+ sl_sleeptimer_is_timer_running(&disk_timerproc_timer_handle,
+ &timer_is_running);
+ if (timer_is_running == false) {
+ // Start a periodic timer 1 ms to generate card control timing
+ sl_sleeptimer_start_periodic_timer_ms(&disk_timerproc_timer_handle,
+ 1,
+ disk_timerproc_timer_callback,
+ (void *)NULL,
+ 0,
+ 0);
+ }
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Sleeptimer callback function to generate card control timing.
+ ******************************************************************************/
+static void disk_timerproc_timer_callback(sl_sleeptimer_timer_handle_t *handle,
+ void *data)
+{
+ (void)handle;
+ (void)data;
+
+ disk_timerproc();
+}
+
+/***************************************************************************//**
+ * Device timer function.
+ * This function must be called from timer interrupt routine in period
+ * of 1 ms to generate card control timing.
+ ******************************************************************************/
+void disk_timerproc(void)
+{
+ WORD n;
+ BYTE s;
+
+ n = sd_card_timer_1; // 1kHz decrement timer stopped at 0
+ if (n) {
+ sd_card_timer_1 = --n;
+ }
+
+ n = sd_card_timer_2;
+ if (n) {
+ sd_card_timer_2 = --n;
+ }
+
+ s = sd_card_status;
+
+#ifdef MMC_CD
+ if (MMC_CD) { // Card is in socket
+ s &= ~STA_NODISK;
+ } else { // Socket empty
+ s |= (STA_NODISK | STA_NOINIT);
+ }
+#else
+ s &= ~STA_NODISK;
+#endif
+ sd_card_status = s;
+}
diff --git a/driver/public/mikroe/nfc2_pn7150/config/brd2703a/mikroe_pn7150_config.h b/driver/public/mikroe/nfc2_pn7150/config/brd2703a/mikroe_pn7150_config.h
new file mode 100644
index 00000000..b89f9677
--- /dev/null
+++ b/driver/public/mikroe/nfc2_pn7150/config/brd2703a/mikroe_pn7150_config.h
@@ -0,0 +1,75 @@
+/***************************************************************************//**
+ * @file mikroe_pn7150_config.h
+ * @brief SCL MIKROE PN7150 Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef MIKROE_PN7150_CONFIG_H_
+#define MIKROE_PN7150_CONFIG_H_
+
+#include "em_gpio.h"
+
+// A CMSIS annotation block starts with the following line:
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// PN7150 I2C ADDRESS
+// <0x28=> I2C_ADDR_0
+// <0x29=> I2C_ADDR_1
+// <0x2A=> I2C_ADDR_2
+// <0x2B=> I2C_ADDR_3
+// Default: 0x28
+#define MIKROE_PN7150_ADDR 0x28
+
+// The block ends with the following line or at the end of the file:
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// MIKROE_PN7150_INT
+// $[GPIO_MIKROE_PN7150_INT]
+#define MIKROE_PN7150_INT_PORT gpioPortB
+#define MIKROE_PN7150_INT_PIN 1
+// [GPIO_MIKROE_PN7150_INT]$
+
+// MIKROE_PN7150_RESET
+// $[GPIO_MIKROE_PN7150_RESET]
+#define MIKROE_PN7150_RESET_PORT gpioPortC
+#define MIKROE_PN7150_RESET_PIN 8
+// [GPIO_MIKROE_PN7150_RESET]$
+
+// <<< sl:end pin_tool >>>
+
+#endif /* MIKROE_PN7150_CONFIG_H_ */
diff --git a/driver/public/mikroe/nfc2_pn7150/config/brd4108a/mikroe_pn7150_config.h b/driver/public/mikroe/nfc2_pn7150/config/brd4108a/mikroe_pn7150_config.h
new file mode 100644
index 00000000..e749f071
--- /dev/null
+++ b/driver/public/mikroe/nfc2_pn7150/config/brd4108a/mikroe_pn7150_config.h
@@ -0,0 +1,75 @@
+/***************************************************************************//**
+ * @file mikroe_pn7150_config.h
+ * @brief SCL MIKROE PN7150 Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef MIKROE_PN7150_CONFIG_H_
+#define MIKROE_PN7150_CONFIG_H_
+
+#include "em_gpio.h"
+
+// A CMSIS annotation block starts with the following line:
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// PN7150 I2C ADDRESS
+// <0x28=> I2C_ADDR_0
+// <0x29=> I2C_ADDR_1
+// <0x2A=> I2C_ADDR_2
+// <0x2B=> I2C_ADDR_3
+// Default: 0x28
+#define MIKROE_PN7150_ADDR 0x28
+
+// The block ends with the following line or at the end of the file:
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// MIKROE_PN7150_INT
+// $[GPIO_MIKROE_PN7150_INT]
+#define MIKROE_PN7150_INT_PORT gpioPortB
+#define MIKROE_PN7150_INT_PIN 3
+// [GPIO_MIKROE_PN7150_INT]$
+
+// MIKROE_PN7150_RESET
+// $[GPIO_MIKROE_PN7150_RESET]
+#define MIKROE_PN7150_RESET_PORT gpioPortC
+#define MIKROE_PN7150_RESET_PIN 6
+// [GPIO_MIKROE_PN7150_RESET]$
+
+// <<< sl:end pin_tool >>>
+
+#endif /* MIKROE_PN7150_CONFIG_H_ */
diff --git a/driver/public/mikroe/nfc2_pn7150/config/brd4314a/mikroe_pn7150_config.h b/driver/public/mikroe/nfc2_pn7150/config/brd4314a/mikroe_pn7150_config.h
new file mode 100644
index 00000000..2fed58b4
--- /dev/null
+++ b/driver/public/mikroe/nfc2_pn7150/config/brd4314a/mikroe_pn7150_config.h
@@ -0,0 +1,75 @@
+/***************************************************************************//**
+ * @file mikroe_pn7150_config.h
+ * @brief SCL MIKROE PN7150 Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef MIKROE_PN7150_CONFIG_H_
+#define MIKROE_PN7150_CONFIG_H_
+
+#include "em_gpio.h"
+
+// A CMSIS annotation block starts with the following line:
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// PN7150 I2C ADDRESS
+// <0x28=> I2C_ADDR_0
+// <0x29=> I2C_ADDR_1
+// <0x2A=> I2C_ADDR_2
+// <0x2B=> I2C_ADDR_3
+// Default: 0x28
+#define MIKROE_PN7150_ADDR 0x28
+
+// The block ends with the following line or at the end of the file:
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// MIKROE_PN7150_INT
+// $[GPIO_MIKROE_PN7150_INT]
+#define MIKROE_PN7150_INT_PORT gpioPortB
+#define MIKROE_PN7150_INT_PIN 3
+// [GPIO_MIKROE_PN7150_INT]$
+
+// MIKROE_PN7150_RESET
+// $[GPIO_MIKROE_PN7150_RESET]
+#define MIKROE_PN7150_RESET_PORT gpioPortC
+#define MIKROE_PN7150_RESET_PIN 6
+// [GPIO_MIKROE_PN7150_RESET]$
+
+// <<< sl:end pin_tool >>>
+
+#endif /* MIKROE_PN7150_CONFIG_H_ */
diff --git a/driver/public/mikroe/nfc2_pn7150/inc/mikroe_pn7150.h b/driver/public/mikroe/nfc2_pn7150/inc/mikroe_pn7150.h
new file mode 100644
index 00000000..f93d48c0
--- /dev/null
+++ b/driver/public/mikroe/nfc2_pn7150/inc/mikroe_pn7150.h
@@ -0,0 +1,280 @@
+/***************************************************************************//**
+ * @file mikroe_pn7150.h
+ * @brief SCL PN7150 Prototypes
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef _MIKROE_PN7150_H_
+#define _MIKROE_PN7150_H_
+
+#include "sl_status.h"
+#include "sl_i2cspm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @addtogroup PN7150 Driver
+ * @brief PN7150 types and APIs.
+ * @{
+ ******************************************************************************/
+
+/**
+ * @brief NFC 2 Click control packet object.
+ * @details Control packet object definition of NFC 2 Click driver.
+ */
+typedef struct
+{
+ uint8_t message_type;
+ uint8_t pck_bound_flag;
+ uint8_t group_ident;
+ uint8_t opcode_ident;
+ uint8_t payload_length;
+ uint8_t payload[256];
+} mikroe_pn7150_control_packet_t;
+
+/**
+ * @brief NFC 2 Click data packet object.
+ * @details Data packet object definition of NFC 2 Click driver.
+ */
+typedef struct
+{
+ uint8_t message_type;
+ uint8_t pck_bound_flag;
+ uint8_t conn_ident;
+ uint8_t payload_length;
+ uint8_t payload[256];
+} mikroe_pn7150_data_packet_t;
+
+/***************************************************************************//**
+ * @brief
+ * Initialization function.
+ *
+ * @param[in] i2cspm_instance
+ * I2CSPM instance
+ *
+ * @return SL_STATUS_OK if there are no errors.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_init(sl_i2cspm_t *i2cspm_instance);
+
+/***************************************************************************//**
+ * @brief
+ * This function sets the IC2SPM instance used by platform functions.
+ *
+ * @param[in] i2cspm_instance
+ * I2CSPM instance
+ *
+ * @return SL_STATUS_OK if there are no errors.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_set_i2csmp_instance(sl_i2cspm_t *i2cspm_instance);
+
+/***************************************************************************//**
+ * @brief NFC 2 default configuration function.
+ * @details This function executes a default configuration of NFC 2
+ * click board.
+ * @param[out] ctrl_pck : Pointer to the memory location of structure.
+ * @return Nothing.
+ * @note This function can consist any necessary configuration or setting to put
+ * device into operating mode.
+ ******************************************************************************/
+void mikroe_pn7150_default_cfg(mikroe_pn7150_control_packet_t *ctrl_pck);
+
+/***************************************************************************//**
+ * @brief NFC 2 I2C writing function.
+ * @details This function writes a desired number of data bytes starting from
+ * the selected register by using I2C serial interface.
+ * @param[in] p_tx_data : Data to be written.
+ * @param[in] n_bytes : Number of bytes to be written.
+ * @return SL_STATUS_OK if there are no errors.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_generic_write(uint8_t *p_tx_data, uint8_t n_bytes);
+
+/***************************************************************************//**
+ * @brief NFC 2 I2C reading function.
+ * @details This function reads a desired number of data bytes starting from
+ * the selected register by using I2C serial interface.
+ * @param[out] p_rx_h_data : Pointer to the memory location where header data be
+ * stored.
+ * @param[out] p_rx_p_data : Pointer to the memory location where payload data
+ * be stored.
+ * @return SL_STATUS_OK if there are no errors.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_generic_read(uint8_t *p_rx_h_data,
+ uint8_t *p_rx_p_data);
+
+/***************************************************************************//**
+ * @brief HW reset function.
+ * @details The function hw reset
+ ******************************************************************************/
+void mikroe_pn7150_hw_reset(void);
+
+/***************************************************************************//**
+ * @brief Get data function.
+ * @details The function read a sequential data starting
+ * of the PN7150 High performance NFC controller on the NFC 2 click board.
+ * @param[out] len : Number od data.
+ * @param[out] p_rx_data : Pointer to the memory location where data be stored.
+ * @return SL_STATUS_OK if there are no errors.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_get_data(uint8_t *len, uint8_t *p_rx_data);
+
+/***************************************************************************//**
+ * @brief Read control packet data function.
+ * @details The function read control packet data
+ * of the PN7150 High performance NFC controller on the NFC 2 click board.
+ * @param[in] ctrl_pck : Pointer to the memory location of structure.
+ * @return SL_STATUS_OK if there are no errors.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_read_ctrl_packet_data(
+ mikroe_pn7150_control_packet_t *ctrl_packet);
+
+/***************************************************************************//**
+ * @brief Write control packet data function.
+ * @details The function write control packet data
+ * to the PN7150 High performance NFC controller on the NFC 2 click board.
+ * @param[in] ctrl_pck : Structure where data be stored.
+ ******************************************************************************/
+void mikroe_pn7150_write_ctrl_packet_data(
+ mikroe_pn7150_control_packet_t ctrl_packet);
+
+/***************************************************************************//**
+ * @brief Check IRQ ststus function.
+ * @details The function check interrupt state and
+ * return state of the INT pin
+ * @return 0 - No active, 1 - Active.
+ ******************************************************************************/
+bool mikroe_pn7150_check_irq(void);
+
+/***************************************************************************//**
+ * @brief Core reset command function.
+ * @details The function set core reset command
+ * to the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_core_reset(void);
+
+/***************************************************************************//**
+ * @brief Core init command function.
+ * @details The function set core init command
+ * to the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_core_init(void);
+
+/***************************************************************************//**
+ * @brief Disable standby mode command function.
+ * @details The function set disable standby mode command
+ * to the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_disable_standby_mode(void);
+
+/***************************************************************************//**
+ * @brief Antenna test function.
+ * @details The function set antenna test
+ * to the PN7150 High performance NFC controller on the NFC 2 click board.
+ * @param[in] ctx : Click context object.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_antenna_test(uint8_t sel_ant);
+
+/***************************************************************************//**
+ * @brief NFC test procedure command function.
+ * @details The function set test procedure command
+ * to the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_test_procedure(void);
+
+/***************************************************************************//**
+ * @brief Core reset command function.
+ * @details The function set core reset command
+ * to the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_core_reset(void);
+
+/***************************************************************************//**
+ * @brief Core initialization command function.
+ * @details The function set core initialization command
+ * to the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_init_core(void);
+
+/***************************************************************************//**
+ * @brief Set default configuration function.
+ * @details The function set default configuration
+ * of the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_core_set_default_config(void);
+
+/***************************************************************************//**
+ * @brief Set protocol configuration function.
+ * @details The function set protocol configuration
+ * of the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_core_set_protocol_config(void);
+
+/***************************************************************************//**
+ * @brief Start discovery command function.
+ * @details The function set start discovery command
+ * of the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_start_discovery(void);
+
+/***************************************************************************//**
+ * @brief Activate remote mifare card command function.
+ * @details The function set activate remote mifare card command
+ * of the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_activate_rmt_mifare_card(void);
+
+/***************************************************************************//**
+ * @brief Authenticate sector command function.
+ * @details The function set authenticate sector command
+ * of the PN7150 High performance NFC controller on the NFC 2 click board.
+ * @param[in] ctx : Click context object.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_authenticate_sector(uint8_t sel_sect_addr);
+
+/***************************************************************************//**
+ * @brief Card disconnected command function.
+ * @details The function set card disconnected command
+ * of the PN7150 High performance NFC controller on the NFC 2 click board.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_card_disconnected(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} (end addtogroup PN7150 Driver) */
+#endif /* _MIKROE_PN7150_H_ */
diff --git a/driver/public/mikroe/nfc2_pn7150/inc/nci_tml.h b/driver/public/mikroe/nfc2_pn7150/inc/nci_tml.h
new file mode 100644
index 00000000..5022e27b
--- /dev/null
+++ b/driver/public/mikroe/nfc2_pn7150/inc/nci_tml.h
@@ -0,0 +1,50 @@
+#ifndef __NCI_TML_H__
+#define __NCI_TML_H__
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @addtogroup NFC Library
+ * @brief Types and definitions for NCI TML.
+ * @{
+ ******************************************************************************/
+
+typedef enum {
+ nci_tml_err_none = 0x00,
+ nci_tml_err_comm_bus = 0x01
+} nci_tml_err_t;
+
+/**************************************************************************//**
+ * @brief
+ * NCI TML transceive function wrapper for PN7150 I2C.
+ *
+ * @param[in] packet
+ * Packet buffer to hold the packet to be sent.
+ *
+ * @returns
+ * Any error code.
+ *****************************************************************************/
+nci_tml_err_t nci_tml_transceive(uint8_t *packet);
+
+/**************************************************************************//**
+ * @brief
+ * NCI TML receive function wrapper for PN7150 I2C.
+ *
+ * @param[out] packet
+ * Packet buffer to hold the received packet.
+ *
+ * @returns
+ * Any error code.
+ *****************************************************************************/
+nci_tml_err_t nci_tml_receive(uint8_t *packet);
+
+/** @} (end addtogroup NFC Library) */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/driver/public/mikroe/nfc2_pn7150/src/mikroe_pn7150.c b/driver/public/mikroe/nfc2_pn7150/src/mikroe_pn7150.c
new file mode 100644
index 00000000..c39bfdb0
--- /dev/null
+++ b/driver/public/mikroe/nfc2_pn7150/src/mikroe_pn7150.c
@@ -0,0 +1,290 @@
+/***************************************************************************//**
+ * @file mikroe_pn7150.c
+ * @brief Mikroe PN7150 Source File
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#include "third_party_hw_drivers_helpers.h"
+#include "mikroe_pn7150_config.h"
+#include "mikroe_pn7150.h"
+#include "nfc2.h"
+
+static nfc2_t nfc2;
+static nfc2_cfg_t nfc2_cfg;
+
+/***************************************************************************//**
+ * Initialization function.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_init(sl_i2cspm_t *i2cspm_instance)
+{
+ if (NULL == i2cspm_instance) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ THIRD_PARTY_HW_DRV_RETCODE_INIT();
+
+ // Configure default i2csmp instance
+ nfc2.i2c.handle = i2cspm_instance;
+
+ // Configure default I2C address
+ nfc2.slave_address = MIKROE_PN7150_ADDR;
+
+ // Call basic setup functions
+ nfc2_cfg_setup(&nfc2_cfg);
+
+#if defined(MIKROE_PN7150_INT_PORT) && defined(MIKROE_PN7150_INT_PIN)
+ nfc2_cfg.int_pin = hal_gpio_pin_name(MIKROE_PN7150_INT_PORT,
+ MIKROE_PN7150_INT_PIN);
+#endif
+
+#if defined(MIKROE_PN7150_RESET_PORT) && defined(MIKROE_PN7150_RESET_PIN)
+ nfc2_cfg.rst = hal_gpio_pin_name(MIKROE_PN7150_RESET_PORT,
+ MIKROE_PN7150_RESET_PIN);
+#endif
+
+ THIRD_PARTY_HW_DRV_RETCODE_TEST(nfc2_init(&nfc2, &nfc2_cfg));
+
+ return THIRD_PARTY_HW_DRV_RETCODE_VALUE;
+}
+
+/***************************************************************************//**
+ * This function sets the IC2SPM instance used by platform functions.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_set_i2csmp_instance(sl_i2cspm_t *i2cspm_instance)
+{
+ if (NULL == i2cspm_instance) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ nfc2.i2c.handle = i2cspm_instance;
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * NFC 2 default configuration function.
+ ******************************************************************************/
+void mikroe_pn7150_default_cfg(mikroe_pn7150_control_packet_t *ctrl_packet)
+{
+ nfc2_default_cfg(&nfc2, (control_packet_t *)ctrl_packet);
+}
+
+/***************************************************************************//**
+ * NFC 2 I2C writing function.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_generic_write(uint8_t *p_tx_data, uint8_t n_bytes)
+{
+ err_t err = NFC2_OK;
+
+ if (NULL == p_tx_data) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+ err = nfc2_generic_write(&nfc2, p_tx_data, n_bytes);
+
+ return (err == NFC2_OK) ? SL_STATUS_OK : SL_STATUS_TRANSMIT;
+}
+
+/***************************************************************************//**
+ * NFC 2 I2C reading function.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_generic_read(uint8_t *p_rx_h_data,
+ uint8_t *p_rx_p_data)
+{
+ err_t err = NFC2_OK;
+
+ if ((NULL == p_rx_h_data) || (NULL == p_rx_p_data)) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ err = nfc2_generic_read(&nfc2, p_rx_h_data, p_rx_p_data);
+
+ return (err == NFC2_OK) ? SL_STATUS_OK : SL_STATUS_TRANSMIT;
+}
+
+/***************************************************************************//**
+ * HW reset function.
+ ******************************************************************************/
+void mikroe_pn7150_hw_reset(void)
+{
+ nfc2_hw_reset(&nfc2);
+}
+
+/***************************************************************************//**
+ * Get data function.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_get_data(uint8_t *len, uint8_t *p_rx_data)
+{
+ if ((NULL == len) || (NULL == p_rx_data)) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+ *len = nfc2_get_data(&nfc2, p_rx_data);
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Read control packet data function.
+ ******************************************************************************/
+sl_status_t mikroe_pn7150_read_ctrl_packet_data(
+ mikroe_pn7150_control_packet_t *ctrl_packet)
+{
+ if (NULL == ctrl_packet) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+ nfc2_read_ctrl_packet_data(&nfc2, (control_packet_t *)ctrl_packet);
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Write control packet data function.
+ ******************************************************************************/
+void mikroe_pn7150_write_ctrl_packet_data(
+ mikroe_pn7150_control_packet_t ctrl_packet)
+{
+ control_packet_t *ctrl_pck = (control_packet_t *)&ctrl_packet;
+ nfc2_write_ctrl_packet_data(&nfc2, *ctrl_pck);
+}
+
+/***************************************************************************//**
+ * Check IRQ ststus function.
+ ******************************************************************************/
+bool mikroe_pn7150_check_irq(void)
+{
+ return nfc2_check_irq(&nfc2);
+}
+
+/***************************************************************************//**
+ * Core reset command function.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_core_reset(void)
+{
+ nfc2_cmd_core_reset(&nfc2);
+}
+
+/***************************************************************************//**
+ * Core init command function.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_core_init(void)
+{
+ nfc2_cmd_core_init(&nfc2);
+}
+
+/***************************************************************************//**
+ * Disable standby mode command function.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_disable_standby_mode(void)
+{
+ nfc2_cmd_disable_standby_mode(&nfc2);
+}
+
+/***************************************************************************//**
+ * Antenna test function.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_antenna_test(uint8_t sel_ant)
+{
+ nfc2_cmd_antenna_test(&nfc2, sel_ant);
+}
+
+/***************************************************************************//**
+ * NFC test procedure command function.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_test_procedure(void)
+{
+ nfc2_cmd_test_procedure(&nfc2);
+}
+
+/***************************************************************************//**
+ * Core reset command function.
+ ******************************************************************************/
+void mikroe_pn7150_core_reset(void)
+{
+ nfc2_core_reset(&nfc2);
+}
+
+/***************************************************************************//**
+ * Core initialization command function.
+ ******************************************************************************/
+void mikroe_pn7150_init_core(void)
+{
+ nfc2_init_core(&nfc2);
+}
+
+/***************************************************************************//**
+ * Set default configuration function.
+ ******************************************************************************/
+void mikroe_pn7150_core_set_default_config(void)
+{
+ nfc2_core_set_default_config(&nfc2);
+}
+
+/***************************************************************************//**
+ * Start discovery command function.
+ ******************************************************************************/
+void mikroe_pn7150_core_set_protocol_config(void)
+{
+ nfc2_core_set_protocol_config(&nfc2);
+}
+
+/***************************************************************************//**
+ * Start discovery command function.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_start_discovery(void)
+{
+ nfc2_cmd_start_discovery(&nfc2);
+}
+
+/***************************************************************************//**
+ * Activate remote mifare card command function.
+ ******************************************************************************/
+void mikroe_pn7150_activate_rmt_mifare_card(void)
+{
+ nfc2_activate_rmt_mifare_card(&nfc2);
+}
+
+/***************************************************************************//**
+ * Authenticate sector command function.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_authenticate_sector(uint8_t sel_sect_addr)
+{
+ nfc2_cmd_authenticate_sector(&nfc2, sel_sect_addr);
+}
+
+/***************************************************************************//**
+ * Card disconnected command function.
+ ******************************************************************************/
+void mikroe_pn7150_cmd_card_disconnected(void)
+{
+ nfc2_cmd_card_disconnected(&nfc2);
+}
diff --git a/driver/public/mikroe/nfc2_pn7150/src/nci_tml.c b/driver/public/mikroe/nfc2_pn7150/src/nci_tml.c
new file mode 100644
index 00000000..c5694c3e
--- /dev/null
+++ b/driver/public/mikroe/nfc2_pn7150/src/nci_tml.c
@@ -0,0 +1,82 @@
+/***************************************************************************//**
+ * @file nci_tml.c
+ * @brief Implementation for using NCI Transport Mapping Layer
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+
+#include "sl_status.h"
+#include "nci_tml.h"
+#include "mikroe_pn7150.h"
+
+/**************************************************************************//**
+ * @brief
+ * NCI TML receive function wrapper for PN71x0 I2C.
+ *
+ * @param[out] packet
+ * Packet buffer to hold the received packet.
+ *
+ * @returns
+ * Any error code.
+ *****************************************************************************/
+nci_tml_err_t nci_tml_receive(uint8_t *packet)
+{
+ sl_status_t ret;
+
+ ret = mikroe_pn7150_generic_read(packet, &packet[3]);
+ if (ret != SL_STATUS_OK) {
+ return nci_tml_err_comm_bus;
+ }
+
+ return nci_tml_err_none;
+}
+
+/**************************************************************************//**
+ * @brief
+ * NCI TML transceive function wrapper for PN71x0 I2C.
+ *
+ * @param[in] packet
+ * Packet buffer to hold the packet to be sent.
+ *
+ * @returns
+ * Any error code.
+ *****************************************************************************/
+nci_tml_err_t nci_tml_transceive(uint8_t *packet)
+{
+ sl_status_t ret;
+
+ ret = mikroe_pn7150_generic_write(packet, packet[2] + 3);
+ if (ret != SL_STATUS_OK) {
+ return nci_tml_err_comm_bus;
+ }
+
+ return nci_tml_err_none;
+}
diff --git a/driver/public/mikroe/oledc_ssd1351/config/brd2703a/mikroe_ssd1351_config.h b/driver/public/mikroe/oledc_ssd1351/config/brd2703a/mikroe_ssd1351_config.h
new file mode 100644
index 00000000..3f1077e6
--- /dev/null
+++ b/driver/public/mikroe/oledc_ssd1351/config/brd2703a/mikroe_ssd1351_config.h
@@ -0,0 +1,72 @@
+/***************************************************************************//**
+ * @file micro_oled_ssd1351_config.h
+ * @brief Micro OLED SSD1351 Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_SSD1351_CONFIG_H_
+#define MIKROE_SSD1351_CONFIG_H_
+
+#define SSD1351_DISPLAY_WIDTH 96
+#define SSD1351_DISPLAY_HEIGHT 96
+#define SSD1351_DISPLAY_COLOR 16
+// <<< sl:start pin_tool >>>
+
+// SSD1351_DC
+// $[GPIO_SSD1351_DC]
+#define SSD1351_DC_PORT gpioPortA
+#define SSD1351_DC_PIN 0
+// [GPIO_SSD1351_DC]$
+
+// SSD1351_RST
+// $[GPIO_SSD1351_RST]
+#define SSD1351_RST_PORT gpioPortC
+#define SSD1351_RST_PIN 8
+// [GPIO_SSD1351_RST]$
+
+// SSD1351_EN
+// $[GPIO_SSD1351_EN]
+#define SSD1351_EN_PORT gpioPortB
+#define SSD1351_EN_PIN 1
+// [GPIO_SSD1351_EN]$
+
+// SSD1351_RW
+// $[GPIO_SSD1351_RW]
+#define SSD1351_RW_PORT gpioPortB
+#define SSD1351_RW_PIN 0
+// [GPIO_SSD1351_RW]$
+// <<< sl:end pin_tool >>>
+
+#endif /* MIKROE_SSD1351_CONFIG_H_ */
diff --git a/driver/public/mikroe/oledc_ssd1351/config/brd4108a/mikroe_ssd1351_config.h b/driver/public/mikroe/oledc_ssd1351/config/brd4108a/mikroe_ssd1351_config.h
new file mode 100644
index 00000000..d6eafbbb
--- /dev/null
+++ b/driver/public/mikroe/oledc_ssd1351/config/brd4108a/mikroe_ssd1351_config.h
@@ -0,0 +1,72 @@
+/***************************************************************************//**
+ * @file micro_oled_ssd1351_config.h
+ * @brief Micro OLED SSD1351 Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_SSD1351_CONFIG_H_
+#define MIKROE_SSD1351_CONFIG_H_
+
+#define SSD1351_DISPLAY_WIDTH 96
+#define SSD1351_DISPLAY_HEIGHT 96
+#define SSD1351_DISPLAY_COLOR 16
+// <<< sl:start pin_tool >>>
+
+// SSD1351_DC
+// $[GPIO_SSD1351_DC]
+#define SSD1351_DC_PORT gpioPortB
+#define SSD1351_DC_PIN 4
+// [GPIO_SSD1351_DC]$
+
+// SSD1351_RST
+// $[GPIO_SSD1351_RST]
+#define SSD1351_RST_PORT gpioPortC
+#define SSD1351_RST_PIN 6
+// [GPIO_SSD1351_RST]$
+
+// SSD1351_EN
+// $[GPIO_SSD1351_EN]
+#define SSD1351_EN_PORT gpioPortB
+#define SSD1351_EN_PIN 3
+// [GPIO_SSD1351_EN]$
+
+// SSD1351_RW
+// $[GPIO_SSD1351_RW]
+#define SSD1351_RW_PORT gpioPortB
+#define SSD1351_RW_PIN 0
+// [GPIO_SSD1351_RW]$
+// <<< sl:end pin_tool >>>
+
+#endif /* MIKROE_SSD1351_CONFIG_H_ */
diff --git a/driver/public/mikroe/oledc_ssd1351/config/brd4314a/mikroe_ssd1351_config.h b/driver/public/mikroe/oledc_ssd1351/config/brd4314a/mikroe_ssd1351_config.h
new file mode 100644
index 00000000..d6eafbbb
--- /dev/null
+++ b/driver/public/mikroe/oledc_ssd1351/config/brd4314a/mikroe_ssd1351_config.h
@@ -0,0 +1,72 @@
+/***************************************************************************//**
+ * @file micro_oled_ssd1351_config.h
+ * @brief Micro OLED SSD1351 Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_SSD1351_CONFIG_H_
+#define MIKROE_SSD1351_CONFIG_H_
+
+#define SSD1351_DISPLAY_WIDTH 96
+#define SSD1351_DISPLAY_HEIGHT 96
+#define SSD1351_DISPLAY_COLOR 16
+// <<< sl:start pin_tool >>>
+
+// SSD1351_DC
+// $[GPIO_SSD1351_DC]
+#define SSD1351_DC_PORT gpioPortB
+#define SSD1351_DC_PIN 4
+// [GPIO_SSD1351_DC]$
+
+// SSD1351_RST
+// $[GPIO_SSD1351_RST]
+#define SSD1351_RST_PORT gpioPortC
+#define SSD1351_RST_PIN 6
+// [GPIO_SSD1351_RST]$
+
+// SSD1351_EN
+// $[GPIO_SSD1351_EN]
+#define SSD1351_EN_PORT gpioPortB
+#define SSD1351_EN_PIN 3
+// [GPIO_SSD1351_EN]$
+
+// SSD1351_RW
+// $[GPIO_SSD1351_RW]
+#define SSD1351_RW_PORT gpioPortB
+#define SSD1351_RW_PIN 0
+// [GPIO_SSD1351_RW]$
+// <<< sl:end pin_tool >>>
+
+#endif /* MIKROE_SSD1351_CONFIG_H_ */
diff --git a/driver/public/mikroe/oledc_ssd1351/inc/mikroe_ssd1351.h b/driver/public/mikroe/oledc_ssd1351/inc/mikroe_ssd1351.h
new file mode 100644
index 00000000..b1603aeb
--- /dev/null
+++ b/driver/public/mikroe/oledc_ssd1351/inc/mikroe_ssd1351.h
@@ -0,0 +1,309 @@
+
+#ifndef MIKROE_SSD1351_H_
+#define MIKROE_SSD1351_H_
+
+#include "oledc.h"
+#include "sl_status.h"
+#include "spidrv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @addtogroup ssd1351 SSD1351 - OLED C Click
+ * @brief Driver for the Mikroe OLED C Click
+ *
+ * @n @section ssd1351_example SSD1351 example
+ *
+ * Basic example @n @n
+ * @code{.c}
+ *
+ * #include "sl_spidrv_instances.h"
+ * #include "mikroe_ssd1351.h"
+ * int main(void)
+ * {
+ * ...
+ *
+ * // Initialize sensor and set mode
+ * mikroe_ssd1351_init(sl_spidrv_mikroe_handle);
+ * mikroe_ssd1351_default_cfg();
+ *
+ * while (true) {
+ *
+ * ...
+ *
+ * }
+ *
+ * } @endcode
+ *
+ * @{
+ ******************************************************************************/
+
+/**
+ * \defgroup font_dir Font Direction
+ * \{
+ */
+#define MIKROE_SSD1351_FO_HORIZONTAL 0x00
+#define MIKROE_SSD1351_FO_VERTICAL 0x01
+#define MIKROE_SSD1351_FO_VERTICAL_COLUMN 0x02
+
+/** \} */
+
+/**
+ * \defgroup remamp_set Remamp Settings
+ * \{
+ */
+#define MIKROE_SSD1351_RMP_INC_HOR 0x00
+#define MIKROE_SSD1351_RMP_INC_VER 0x01
+#define MIKROE_SSD1351_RMP_COLOR_NOR 0x00
+#define MIKROE_SSD1351_RMP_COLOR_REV 0x02
+#define MIKROE_SSD1351_RMP_SEQ_RGB 0x00
+#define MIKROE_SSD1351_RMP_SEQ_BGR 0x04
+#define MIKROE_SSD1351_RMP_SCAN_NOR 0x00
+#define MIKROE_SSD1351_RMP_SCAN_REV 0x10
+#define MIKROE_SSD1351_RMP_SPLIT_DISABLE 0x00
+#define MIKROE_SSD1351_RMP_SPLIT_ENABLE 0x20
+#define MIKROE_SSD1351_COLOR_65K 0x00
+#define MIKROE_SSD1351_COLOR_262K 0x80
+#define MIKROE_SSD1351_IMG_HEAD 0x06
+
+/** \} */
+
+/**
+ * \defgroup dev_proper Device Properties
+ * \{
+ */
+#define MIKROE_SSD1351_SCREEN_WIDTH 0x60
+#define MIKROE_SSD1351_SCREEN_HEIGHT 0x60
+#define MIKROE_SSD1351_SCREEN_SIZE 0x2400
+#define MIKROE_SSD1351_ROW_OFF 0x00
+#define MIKROE_SSD1351_COL_OFF 0x10
+
+/** \} */
+
+/**
+ * \defgroup commands Commands
+ * \{
+ */
+#define MIKROE_SSD1351_SET_COL_ADDRESS 0x15
+#define MIKROE_SSD1351_SET_ROW_ADDRESS 0x75
+#define MIKROE_SSD1351_WRITE_RAM 0x5C
+#define MIKROE_SSD1351_READ_RAM 0x5D
+#define MIKROE_SSD1351_SET_REMAP 0xA0
+#define MIKROE_SSD1351_SET_START_LINE 0xA1
+#define MIKROE_SSD1351_SET_OFFSET 0xA2
+#define MIKROE_SSD1351_MODE_OFF 0xA4
+#define MIKROE_SSD1351_MODE_ON 0xA5
+#define MIKROE_SSD1351_MODE_NORMAL 0xA6
+#define MIKROE_SSD1351_MODE_INVERSE 0xA7
+#define MIKROE_SSD1351_FUNCTION 0xAB
+#define MIKROE_SSD1351_SLEEP_ON 0xAE
+#define MIKROE_SSD1351_SLEEP_OFF 0xAF
+#define MIKROE_SSD1351_NOP 0xB0
+#define MIKROE_SSD1351_SET_RESET_PRECH 0xB1
+#define MIKROE_SSD1351_ENHANCEMENT 0xB2
+#define MIKROE_SSD1351_CLOCK_DIV 0xB3
+#define MIKROE_SSD1351_VSL 0xB4
+#define MIKROE_SSD1351_GPIO 0xB5
+#define MIKROE_SSD1351_SETSEC_PRECH 0xB6
+#define MIKROE_SSD1351_GREY_SCALE 0xB8
+#define MIKROE_SSD1351_LUT 0xB9
+#define MIKROE_SSD1351_PRECH_VOL 0xBB
+#define MIKROE_SSD1351_VCOMH 0xBE
+#define MIKROE_SSD1351_CONTRAST 0xC1
+#define MIKROE_SSD1351_MASTER_CONTRAST 0xC7
+#define MIKROE_SSD1351_MUX_RATIO 0xCA
+#define MIKROE_SSD1351_COMMAND_LOCK 0xFD
+#define MIKROE_SSD1351_SCROLL_HOR 0x96
+#define MIKROE_SSD1351_START_MOV 0x9E
+#define MIKROE_SSD1351_STOP_MOV 0x9F
+
+#define MIKROE_SSD1351_DEFAULT_MUX_RATIO 95
+#define MIKROE_SSD1351_DEFAULT_START_LINE 0x80
+#define MIKROE_SSD1351_DEFAULT_OFFSET 0x20
+
+#define MIKROE_SSD1351_DEFAULT_OLED_LOCK 0x12
+#define MIKROE_SSD1351_DEFAULT_CMD_LOCK 0xB1
+#define MIKROE_SSD1351_DEFAULT_DIVSET 0xF1
+#define MIKROE_SSD1351_DEFAULT_PRECHARGE 0x32
+#define MIKROE_SSD1351_DEFAULT_VCOMH 0x05
+#define MIKROE_SSD1351_DEFAULT_MASTER_CONT 0xCF
+#define MIKROE_SSD1351_DEFAULT_PRECHARGE_2 0x01
+
+/***************************************************************************//**
+ * @brief
+ * Initialization function.
+ *
+ * @param[in] spi_instance
+ * SPI instance
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_init(SPIDRV_Handle_t spi_instance);
+
+/***************************************************************************//**
+ * @brief
+ * This function sets the SPI instance used by platform functions
+ *
+ * @param[in] spi_instance
+ * SPI instance
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors
+ * SL_STATUS_INVALID_PARAMETER if spi_instance is null
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_set_spi_instance(SPIDRV_Handle_t spi_instance);
+
+/***************************************************************************//**
+ * @brief
+ * Default Configuration function.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_default_cfg(void);
+
+/***************************************************************************//**
+ * @brief
+ * Enable/Disable display.
+ *
+ * @param[in] state 1 - ON / 0 - OFF.
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_enable(bool state);
+
+/***************************************************************************//**
+ * @brief
+ * Hardware Reset.
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_reset(void);
+
+/***************************************************************************//**
+ * @brief
+ * Command Send with more argument.
+ *
+ * @param[in] command Command to be sent.
+ * @param[in] args Pointer to command argument.
+ * @param[in] args_len Argument size in bytes.
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_more_arg_commands(uint8_t command,
+ uint8_t *args,
+ uint16_t args_len);
+
+/***************************************************************************//**
+ * @brief
+ * Command Send with one argument.
+ *
+ * @param[in] ctx Context object.
+ * @param[in] cmd Command to be sent.
+ * @param[in] args One command argument.
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_one_arg_commands(uint8_t command, uint8_t args);
+
+/***************************************************************************//**
+ * @brief
+ * Fill Screen.
+ *
+ * @param[in] color RGB color.
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_fill_screen(uint16_t color);
+
+/***************************************************************************//**
+ * @brief
+ * Draw Rectangle.
+ *
+ * @param[in] col_off Column offset from the left border of the screen.
+ * @param[in] row_off Row offset from the top border of the screen.
+ * @param[in] col_end Column end offset also counted from the left border.
+ * @param[in] row_end Row offset also counted from the top border.
+ * @param[in] color RGB color.
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_rectangle(uint8_t col_off,
+ uint8_t row_off,
+ uint8_t col_end,
+ uint8_t row_end,
+ uint16_t color);
+
+/***************************************************************************//**
+ * @brief
+ * Draw BMP Image.
+ *
+ * @param[in] col_off Column offset from the left border of the screen.
+ * @param[in] row_off Row offset from the top border of the screen.
+ * @param[in] img Pointer to bmp image.
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_image(const uint8_t *img,
+ uint8_t col_off,
+ uint8_t row_off);
+
+/***************************************************************************//**
+ * @brief
+ * Draw Text.
+ *
+ * @param[in] text Text string.
+ * @param[in] x Column offset from the left border of the screen.
+ * @param[in] y Row offset from the top border of the screen.
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_text(uint8_t *text, uint16_t x, uint16_t y);
+
+/***************************************************************************//**
+ * @brief
+ * Font Setup.
+ *
+ * @param[in] font_s Pointer to font definition.
+ * @param[in] color Text color.
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_set_font(const uint8_t *font_s, uint16_t color);
+
+/***************************************************************************//**
+ * @brief
+ * Set Contrast.
+ *
+ * @param[in] contrast 0-255.
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_set_contrast(uint8_t contrast);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver/public/mikroe/oledc_ssd1351/inc/mikroe_ssd1351_image.h b/driver/public/mikroe/oledc_ssd1351/inc/mikroe_ssd1351_image.h
new file mode 100644
index 00000000..6b82cc47
--- /dev/null
+++ b/driver/public/mikroe/oledc_ssd1351/inc/mikroe_ssd1351_image.h
@@ -0,0 +1,1747 @@
+#include "stdint.h"
+
+const uint8_t mikroe_with_slogan[] =
+{
+ 0x00,
+ 0x10,
+ 0x60, 0x00,
+ 0x18, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x9C, 0x79, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x1C, 0xE7, 0x92, 0x94, 0xBE, 0xF7, 0x7D, 0xEF, 0x51, 0x8C, 0x1C,
+ 0xE7, 0xDF, 0xFF,
+ 0x92, 0x94, 0x59, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xF7,
+ 0xBD, 0x7D, 0xEF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xBD, 0x30, 0x84, 0x30, 0x84, 0x30, 0x84, 0x30,
+ 0x84, 0x30, 0x84,
+ 0x30, 0x84, 0x30, 0x84, 0x30, 0x84, 0x30, 0x84, 0x30, 0x84, 0x30, 0x84, 0x30,
+ 0x84, 0xF3, 0x9C,
+ 0x9E, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xF7, 0x14, 0xA5, 0x30,
+ 0x84, 0x30, 0x84,
+ 0x30, 0x84, 0x30, 0x84, 0x30, 0x84, 0x30, 0x84, 0x30, 0x84, 0x30, 0x84, 0x30,
+ 0x84, 0x30, 0x84,
+ 0x30, 0x84, 0x30, 0x84, 0x18, 0xC6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+ 0xFF, 0x53, 0xFF,
+ 0x2F, 0xFF, 0x2F, 0xFF, 0x2F, 0xFF, 0x2F, 0xFF, 0x2F, 0xFF, 0x2F, 0xFF, 0x2F,
+ 0xFF, 0x2F, 0xFF,
+ 0x2F, 0xFF, 0x2F, 0xFF, 0x2F, 0xFF, 0x2F, 0xFF, 0x2F, 0xFF, 0x30, 0xFF, 0xBB,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x3C, 0xE7, 0x00, 0x00, 0x61, 0x08, 0x38, 0xC6, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0x3C, 0xE7, 0x24, 0x21, 0x00, 0x00, 0xB6, 0xB5, 0x14, 0xA5, 0x00, 0x00, 0x10,
+ 0x84, 0x79, 0xCE,
+ 0x00, 0x00, 0xAA, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xF3, 0x9C, 0x45, 0x29, 0x00,
+ 0x00, 0xAE, 0x73,
+ 0xFF, 0xFF, 0x14, 0xA5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xC3, 0x18, 0x79, 0xCE, 0xFF, 0xFF, 0xBE, 0xF7, 0xC7, 0x39, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x84, 0xFF, 0xFF, 0xDD, 0xFF, 0x85,
+ 0xFE, 0x41, 0xFE,
+ 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41,
+ 0xFE, 0x41, 0xFE,
+ 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x31,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x1C, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x82, 0x10, 0x59, 0xCE, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x3C, 0xE7,
+ 0x24, 0x21, 0x00, 0x00, 0x00, 0x00, 0x96, 0xB5, 0xF3, 0x9C, 0x00, 0x00, 0xEF,
+ 0x7B, 0x59, 0xCE,
+ 0x00, 0x00, 0x8A, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x9E, 0xF7, 0x92, 0x94, 0xE3, 0x18, 0x00, 0x00, 0x00, 0x00, 0x8A,
+ 0x52, 0xBA, 0xD6,
+ 0xFF, 0xFF, 0x69, 0x4A, 0x00, 0x00, 0x14, 0xA5, 0x96, 0xB5, 0x96, 0xB5, 0x96,
+ 0xB5, 0x96, 0xB5,
+ 0x96, 0xB5, 0x96, 0xB5, 0x96, 0xB5, 0x96, 0xB5, 0x96, 0xB5, 0x96, 0xB5, 0x96,
+ 0xB5, 0xEB, 0x5A,
+ 0x00, 0x00, 0x65, 0x29, 0xFF, 0xFF, 0x34, 0xA5, 0x00, 0x00, 0xE7, 0x39, 0x96,
+ 0xB5, 0x96, 0xB5,
+ 0x96, 0xB5, 0x96, 0xB5, 0x96, 0xB5, 0x96, 0xB5, 0x96, 0xB5, 0x96, 0xB5, 0x96,
+ 0xB5, 0x96, 0xB5,
+ 0x96, 0xB5, 0x34, 0xA5, 0x82, 0x10, 0x41, 0x08, 0x7D, 0xEF, 0x32, 0xFF, 0x41,
+ 0xFE, 0xEC, 0xFE,
+ 0x98, 0xFF, 0x98, 0xFF, 0x98, 0xFF, 0x98, 0xFF, 0x98, 0xFF, 0x98, 0xFF, 0x98,
+ 0xFF, 0x98, 0xFF,
+ 0x98, 0xFF, 0x98, 0xFF, 0x98, 0xFF, 0x98, 0xFF, 0x98, 0xFF, 0x99, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x1C, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x10, 0x79,
+ 0xCE, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C,
+ 0xE7, 0x65, 0x29,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0xB5, 0xF3, 0x9C, 0x00, 0x00, 0xEF,
+ 0x7B, 0x59, 0xCE,
+ 0x00, 0x00, 0x8A, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x7D, 0xEF,
+ 0x10, 0x84, 0xA2, 0x10, 0x00, 0x00, 0x20, 0x00, 0xEB, 0x5A, 0x9A, 0xD6, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x28, 0x42, 0x00, 0x00, 0x9E, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0x45, 0x29, 0x00, 0x00, 0xDB, 0xDE, 0x30, 0x84, 0x00, 0x00, 0x34, 0xA5, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x8A, 0x52, 0x00, 0x00, 0x9A, 0xD6, 0x0E, 0xFF, 0x41,
+ 0xFE, 0x97, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x1C, 0xE7, 0x00, 0x00, 0x65, 0x29, 0x51, 0x8C, 0x00, 0x00, 0xA2,
+ 0x10, 0x9A, 0xD6,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xEF, 0x65,
+ 0x29, 0x00, 0x00,
+ 0x69, 0x4A, 0x4D, 0x6B, 0x00, 0x00, 0x96, 0xB5, 0xF3, 0x9C, 0x00, 0x00, 0xEF,
+ 0x7B, 0x59, 0xCE,
+ 0x00, 0x00, 0x8A, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0xE7, 0xAE,
+ 0x73, 0x61, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x45, 0x29, 0xFB, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x28, 0x42, 0x00, 0x00, 0x9E, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0x45, 0x29, 0x00, 0x00, 0x9A, 0xD6, 0x30, 0x84, 0x00, 0x00, 0x34, 0xA5, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0x52, 0x00, 0x00, 0x9A, 0xD6, 0x0E, 0xFF, 0x41,
+ 0xFE, 0x0E, 0xFF,
+ 0xB9, 0xFF, 0xB9, 0xFF, 0xB9, 0xFF, 0xB9, 0xFF, 0xB9, 0xFF, 0xB9, 0xFF, 0xB9,
+ 0xFF, 0xB9, 0xFF,
+ 0xB9, 0xFF, 0xB9, 0xFF, 0xB9, 0xFF, 0xB9, 0xFF, 0xB9, 0xFF, 0xB9, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x1C, 0xE7, 0x00, 0x00, 0xE7, 0x39, 0xFF, 0xFF, 0x51, 0x8C, 0x00,
+ 0x00, 0xC3, 0x18,
+ 0xBA, 0xD6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D, 0xEF, 0x86, 0x31, 0x00,
+ 0x00, 0x49, 0x4A,
+ 0xBE, 0xF7, 0x30, 0x84, 0x00, 0x00, 0x96, 0xB5, 0xF3, 0x9C, 0x00, 0x00, 0xEF,
+ 0x7B, 0x59, 0xCE,
+ 0x00, 0x00, 0x69, 0x4A, 0xFF, 0xFF, 0xFB, 0xDE, 0x4D, 0x6B, 0x41, 0x08, 0x00,
+ 0x00, 0x41, 0x08,
+ 0x41, 0x08, 0x00, 0x00, 0x45, 0x29, 0x7D, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x28, 0x42, 0x00, 0x00, 0x92, 0x94, 0x38, 0xC6, 0x38, 0xC6, 0x38,
+ 0xC6, 0x38, 0xC6,
+ 0x38, 0xC6, 0x38, 0xC6, 0x38, 0xC6, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xD7,
+ 0xBD, 0xEB, 0x5A,
+ 0x00, 0x00, 0xE3, 0x18, 0xDF, 0xFF, 0x30, 0x84, 0x00, 0x00, 0x34, 0xA5, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0x52, 0x00, 0x00, 0x9A, 0xD6, 0x0E, 0xFF, 0x41,
+ 0xFE, 0x41, 0xFE,
+ 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41,
+ 0xFE, 0x41, 0xFE,
+ 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x41, 0xFE, 0x31,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x1C, 0xE7, 0x00, 0x00, 0xE7, 0x39, 0xFF, 0xFF, 0xFF, 0xFF, 0x30,
+ 0x84, 0x00, 0x00,
+ 0xC3, 0x18, 0xDB, 0xDE, 0xFF, 0xFF, 0x7D, 0xEF, 0xA6, 0x31, 0x00, 0x00, 0x28,
+ 0x42, 0xBE, 0xF7,
+ 0xFF, 0xFF, 0x30, 0x84, 0x00, 0x00, 0x96, 0xB5, 0xF3, 0x9C, 0x00, 0x00, 0xEF,
+ 0x7B, 0x59, 0xCE,
+ 0x00, 0x00, 0x00, 0x00, 0xE7, 0x39, 0x20, 0x00, 0x00, 0x00, 0x82, 0x10, 0xEF,
+ 0x7B, 0x5D, 0xEF,
+ 0x1C, 0xE7, 0x86, 0x31, 0x00, 0x00, 0x24, 0x21, 0xBA, 0xD6, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x28, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x41, 0x08, 0xD7, 0xBD, 0xFF, 0xFF, 0x30, 0x84, 0x00, 0x00, 0x34, 0xA5, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0x52, 0x00, 0x00, 0x9A, 0xD6, 0x0E, 0xFF, 0x41,
+ 0xFE, 0x84, 0xFE,
+ 0xEB, 0xFE, 0xEB, 0xFE, 0xEB, 0xFE, 0xEB, 0xFE, 0xEB, 0xFE, 0xEB, 0xFE, 0xEB,
+ 0xFE, 0xEB, 0xFE,
+ 0xEB, 0xFE, 0xEB, 0xFE, 0xEB, 0xFE, 0xEB, 0xFE, 0xEB, 0xFE, 0xEB, 0xFE, 0x99,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x1C, 0xE7, 0x00, 0x00, 0xE7, 0x39, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xEF, 0x7B,
+ 0x00, 0x00, 0xE3, 0x18, 0x79, 0xCE, 0xC7, 0x39, 0x00, 0x00, 0x08, 0x42, 0x9E,
+ 0xF7, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x30, 0x84, 0x00, 0x00, 0x96, 0xB5, 0xF3, 0x9C, 0x00, 0x00, 0xEF,
+ 0x7B, 0x59, 0xCE,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x18, 0x51, 0x8C, 0x9E, 0xF7, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xBE, 0xF7, 0xAA, 0x52, 0x00, 0x00, 0x82, 0x10, 0xB6, 0xB5, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x28, 0x42, 0x00, 0x00, 0xA6, 0x31, 0x4D, 0x6B, 0x4D, 0x6B, 0x4D,
+ 0x6B, 0x4D, 0x6B,
+ 0x4D, 0x6B, 0x4D, 0x6B, 0x4D, 0x6B, 0x4D, 0x6B, 0x4D, 0x6B, 0x28, 0x42, 0x00,
+ 0x00, 0x00, 0x00,
+ 0xB2, 0x94, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x84, 0x00, 0x00, 0x34, 0xA5, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0x52, 0x00, 0x00, 0x9A, 0xD6, 0x0E, 0xFF, 0x41,
+ 0xFE, 0x76, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x1C, 0xE7, 0x00, 0x00, 0xE7, 0x39, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xAE, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x39, 0x9E, 0xF7, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x30, 0x84, 0x00, 0x00, 0x96, 0xB5, 0xF3, 0x9C, 0x00, 0x00, 0xEF,
+ 0x7B, 0x59, 0xCE,
+ 0x00, 0x00, 0x61, 0x08, 0xB2, 0x94, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x84, 0x00, 0x00, 0x20, 0x00, 0x71,
+ 0x8C, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x28, 0x42, 0x00, 0x00, 0x9A, 0xD6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C,
+ 0x63, 0x00, 0x00,
+ 0x86, 0x31, 0x7D, 0xEF, 0xFF, 0xFF, 0x71, 0x8C, 0x00, 0x00, 0xEF, 0x7B, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xDF, 0xFF, 0xA6, 0x31, 0x00, 0x00, 0xFB, 0xDE, 0x2F, 0xFF, 0x41,
+ 0xFE, 0x52, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x1C, 0xE7, 0x00, 0x00, 0xE7, 0x39, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x6D, 0x6B, 0x00, 0x00, 0xA6, 0x31, 0x9E, 0xF7, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x30, 0x84, 0x00, 0x00, 0x96, 0xB5, 0xF3, 0x9C, 0x00, 0x00, 0xEF,
+ 0x7B, 0x59, 0xCE,
+ 0x00, 0x00, 0x8A, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0xAD, 0x61, 0x08, 0x00,
+ 0x00, 0x92, 0x94,
+ 0xFF, 0xFF, 0x28, 0x42, 0x00, 0x00, 0xBA, 0xD6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF,
+ 0xFF, 0xAA, 0x52,
+ 0x00, 0x00, 0x28, 0x42, 0xFF, 0xFF, 0xDB, 0xDE, 0x20, 0x00, 0x00, 0x00, 0xA2,
+ 0x10, 0xA2, 0x10,
+ 0xA2, 0x10, 0xA2, 0x10, 0xA2, 0x10, 0xA2, 0x10, 0xA2, 0x10, 0xA2, 0x10, 0xA2,
+ 0x10, 0xA2, 0x10,
+ 0xA2, 0x10, 0x61, 0x08, 0x00, 0x00, 0xA6, 0x31, 0xFF, 0xFF, 0xBA, 0xFF, 0x61,
+ 0xFE, 0x41, 0xFE,
+ 0x63, 0xFE, 0x63, 0xFE, 0x63, 0xFE, 0x63, 0xFE, 0x63, 0xFE, 0x63, 0xFE, 0x63,
+ 0xFE, 0x63, 0xFE,
+ 0x63, 0xFE, 0x63, 0xFE, 0x63, 0xFE, 0x63, 0xFE, 0x63, 0xFE, 0x63, 0xFE, 0x75,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x9E, 0xF7, 0x24, 0x21, 0x4D, 0x6B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0xB5, 0x7D, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x75, 0xAD, 0xE3, 0x18, 0xBA, 0xD6, 0x18, 0xC6, 0xA2, 0x10, 0x55,
+ 0xAD, 0x3C, 0xE7,
+ 0xE3, 0x18, 0xEF, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x79, 0xCE, 0x08,
+ 0x42, 0x18, 0xC6,
+ 0xFF, 0xFF, 0xAE, 0x73, 0x04, 0x21, 0x7D, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xDF, 0xFF,
+ 0x4D, 0x6B, 0x92, 0x94, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0xBD, 0x86, 0x31, 0x82,
+ 0x10, 0x82, 0x10,
+ 0x82, 0x10, 0x82, 0x10, 0x82, 0x10, 0x82, 0x10, 0x82, 0x10, 0x82, 0x10, 0x82,
+ 0x10, 0x82, 0x10,
+ 0x82, 0x10, 0x82, 0x10, 0x69, 0x4A, 0x1C, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0x97,
+ 0xFF, 0xA8, 0xFE,
+ 0x85, 0xFE, 0x85, 0xFE, 0x85, 0xFE, 0x85, 0xFE, 0x85, 0xFE, 0x85, 0xFE, 0x85,
+ 0xFE, 0x85, 0xFE,
+ 0x85, 0xFE, 0x85, 0xFE, 0x85, 0xFE, 0x85, 0xFE, 0x85, 0xFE, 0x85, 0xFE, 0x74,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x6D, 0x6B, 0xA6, 0x31, 0x69, 0x4A, 0xF3, 0x9C, 0x9A, 0xD6, 0xDB,
+ 0xDE, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0x75, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xF7, 0x6D,
+ 0x6B, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x59, 0xCE,
+ 0xF3, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0x18, 0xC6, 0xD3, 0x9C, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x75, 0xAD, 0x96, 0xB5, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0x9E, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x6D, 0x6B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0x7B, 0x59, 0xCE, 0xFF, 0xFF, 0xBA, 0xD6, 0xDB,
+ 0xDE, 0xBE, 0xF7,
+ 0x79, 0xCE, 0x59, 0xCE, 0x59, 0xCE, 0x1C, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0x79,
+ 0xCE, 0x1C, 0xE7,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x79, 0xCE, 0xDB,
+ 0xDE, 0xFF, 0xFF,
+ 0xBE, 0xF7, 0x38, 0xC6, 0x5D, 0xEF, 0xFF, 0xFF, 0x1C, 0xE7, 0xFF, 0xFF, 0x1C,
+ 0xE7, 0xFF, 0xFF,
+ 0x96, 0xB5, 0xFF, 0xFF, 0xBA, 0xD6, 0x18, 0xC6, 0x9E, 0xF7, 0xFF, 0xFF, 0xBE,
+ 0xF7, 0x18, 0xC6,
+ 0xBA, 0xD6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xF7, 0x38, 0xC6, 0x7D,
+ 0xEF, 0xFF, 0xFF,
+ 0xDB, 0xDE, 0x59, 0xCE, 0x59, 0xCE, 0x79, 0xCE, 0xFF, 0xFF, 0x9E, 0xF7, 0x8A,
+ 0x52, 0x59, 0xCE,
+ 0xDF, 0xFF, 0xFF, 0xFF, 0x3C, 0xE7, 0x59, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C,
+ 0xE7, 0xD3, 0x9C,
+ 0xB2, 0x94, 0xFF, 0xFF, 0x3C, 0xE7, 0xB2, 0x94, 0xB2, 0x94, 0xFF, 0xFF, 0xFB,
+ 0xDE, 0x79, 0xCE,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xDE, 0x10, 0x84, 0x75, 0xAD, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xBA, 0xD6,
+ 0x2C, 0x63, 0x5D, 0xEF, 0xDF, 0xFF, 0x38, 0xC6, 0x5D, 0xEF, 0xFF, 0xFF, 0x9E,
+ 0xF7, 0x38, 0xC6,
+ 0x9E, 0xF7, 0xFF, 0xFF, 0xEB, 0x5A, 0xFF, 0xFF, 0x5D, 0xEF, 0x38, 0xC6, 0xDF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0x7B, 0x59, 0xCE, 0xFF, 0xFF, 0x14, 0xA5, 0x96,
+ 0xB5, 0x18, 0xC6,
+ 0xCB, 0x5A, 0xEB, 0x5A, 0xEF, 0x7B, 0x28, 0x42, 0x9E, 0xF7, 0x71, 0x8C, 0x51,
+ 0x8C, 0x8A, 0x52,
+ 0x5D, 0xEF, 0xFB, 0xDE, 0x59, 0xCE, 0x5D, 0xEF, 0x59, 0xCE, 0x0C, 0x63, 0x14,
+ 0xA5, 0xFF, 0xFF,
+ 0xF7, 0xBD, 0xF3, 0x9C, 0x49, 0x4A, 0xFF, 0xFF, 0x69, 0x4A, 0xFF, 0xFF, 0xAA,
+ 0x52, 0xFF, 0xFF,
+ 0xAA, 0x52, 0xFF, 0xFF, 0x49, 0x4A, 0xF3, 0x9C, 0xEB, 0x5A, 0xFF, 0xFF, 0x8A,
+ 0x52, 0x14, 0xA5,
+ 0x69, 0x4A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0x63, 0xF3, 0x9C, 0x8A,
+ 0x52, 0xFF, 0xFF,
+ 0x28, 0x42, 0xD3, 0x9C, 0xE7, 0x39, 0x10, 0x84, 0x71, 0x8C, 0x9E, 0xF7, 0x08,
+ 0x42, 0x92, 0x94,
+ 0x8E, 0x73, 0x5D, 0xEF, 0x8A, 0x52, 0x71, 0x8C, 0x30, 0x84, 0xDB, 0xDE, 0x8A,
+ 0x52, 0x10, 0x84,
+ 0xB2, 0x94, 0xDB, 0xDE, 0x8A, 0x52, 0xEF, 0x7B, 0xB2, 0x94, 0xBA, 0xD6, 0xCB,
+ 0x5A, 0xEF, 0x7B,
+ 0x14, 0xA5, 0x38, 0xC6, 0xEB, 0x5A, 0x6D, 0x6B, 0x75, 0xAD, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xBA, 0xD6,
+ 0x69, 0x4A, 0xBA, 0xD6, 0x4D, 0x6B, 0xB2, 0x94, 0x08, 0x42, 0xDF, 0xFF, 0xAA,
+ 0x52, 0xF3, 0x9C,
+ 0x69, 0x4A, 0xFF, 0xFF, 0xEB, 0x5A, 0xFF, 0xFF, 0x8A, 0x52, 0xF3, 0x9C, 0xFB,
+ 0xDE, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0x7B, 0x59, 0xCE, 0xFF, 0xFF, 0x14, 0xA5, 0x96,
+ 0xB5, 0x18, 0xC6,
+ 0x92, 0x94, 0x92, 0x94, 0x18, 0xC6, 0xAE, 0x73, 0xFB, 0xDE, 0xCB, 0x5A, 0x6D,
+ 0x6B, 0x0C, 0x63,
+ 0xDB, 0xDE, 0x96, 0xB5, 0x51, 0x8C, 0x79, 0xCE, 0x7D, 0xEF, 0x2C, 0x63, 0x6D,
+ 0x6B, 0xDF, 0xFF,
+ 0x34, 0xA5, 0x6D, 0x6B, 0xA6, 0x31, 0xFF, 0xFF, 0x30, 0x84, 0x34, 0xA5, 0xEF,
+ 0x7B, 0xFF, 0xFF,
+ 0xAA, 0x52, 0xFF, 0xFF, 0xAA, 0x52, 0xFF, 0xFF, 0xAA, 0x52, 0xBE, 0xF7, 0xAA,
+ 0x52, 0xFF, 0xFF,
+ 0xAA, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x86, 0x31, 0x8E, 0x73, 0x2C,
+ 0x63, 0xFF, 0xFF,
+ 0xAA, 0x52, 0xBE, 0xF7, 0xEB, 0x5A, 0x3C, 0xE7, 0x8E, 0x73, 0x9E, 0xF7, 0x2C,
+ 0x63, 0xFF, 0xFF,
+ 0x69, 0x4A, 0x18, 0xC6, 0xE7, 0x39, 0x6D, 0x6B, 0x92, 0x94, 0x34, 0xA5, 0x34,
+ 0xA5, 0x38, 0xC6,
+ 0xB2, 0x94, 0x55, 0xAD, 0x34, 0xA5, 0xF7, 0xBD, 0xB2, 0x94, 0x34, 0xA5, 0x49,
+ 0x4A, 0x6D, 0x6B,
+ 0x34, 0xA5, 0x51, 0x8C, 0x18, 0xC6, 0x34, 0xA5, 0x75, 0xAD, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xBA, 0xD6,
+ 0xEF, 0x7B, 0xFF, 0xFF, 0xAA, 0x52, 0xFF, 0xFF, 0x6D, 0x6B, 0x3C, 0xE7, 0xAA,
+ 0x52, 0xFF, 0xFF,
+ 0xCB, 0x5A, 0xDF, 0xFF, 0xEB, 0x5A, 0xFF, 0xFF, 0x92, 0x94, 0x0C, 0x63, 0x38,
+ 0xC6, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0x7B, 0x59, 0xCE, 0xFF, 0xFF, 0x14, 0xA5, 0x96,
+ 0xB5, 0x18, 0xC6,
+ 0x92, 0x94, 0x92, 0x94, 0x18, 0xC6, 0xAE, 0x73, 0xFB, 0xDE, 0x51, 0x8C, 0x71,
+ 0x8C, 0x34, 0xA5,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xEF, 0x75, 0xAD, 0x69,
+ 0x4A, 0x7D, 0xEF,
+ 0xCB, 0x5A, 0x18, 0xC6, 0x28, 0x42, 0xFF, 0xFF, 0x1C, 0xE7, 0xE3, 0x18, 0xBA,
+ 0xD6, 0xFF, 0xFF,
+ 0xAA, 0x52, 0xFF, 0xFF, 0xAA, 0x52, 0xFF, 0xFF, 0xAA, 0x52, 0xFF, 0xFF, 0x28,
+ 0x42, 0x96, 0xB5,
+ 0x69, 0x4A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCB, 0x5A, 0x55, 0xAD, 0xB6,
+ 0xB5, 0xFF, 0xFF,
+ 0xAA, 0x52, 0xBE, 0xF7, 0xEB, 0x5A, 0x3C, 0xE7, 0x6D, 0x6B, 0x9E, 0xF7, 0x49,
+ 0x4A, 0xF3, 0x9C,
+ 0xEF, 0x7B, 0x5D, 0xEF, 0x49, 0x4A, 0x96, 0xB5, 0x79, 0xCE, 0x79, 0xCE, 0xEB,
+ 0x5A, 0xB2, 0x94,
+ 0xB2, 0x94, 0x79, 0xCE, 0xEB, 0x5A, 0x71, 0x8C, 0xB2, 0x94, 0xBA, 0xD6, 0xAA,
+ 0x52, 0x96, 0xB5,
+ 0xDB, 0xDE, 0xB6, 0xB5, 0x8E, 0x73, 0xEF, 0x7B, 0x75, 0xAD, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xBA, 0xD6,
+ 0xEF, 0x7B, 0xFF, 0xFF, 0x8E, 0x73, 0x34, 0xA5, 0x49, 0x4A, 0xDF, 0xFF, 0xCB,
+ 0x5A, 0x96, 0xB5,
+ 0x8A, 0x52, 0xFF, 0xFF, 0xEB, 0x5A, 0xFF, 0xFF, 0x96, 0xB5, 0xF3, 0x9C, 0x30,
+ 0x84, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xD6, 0x7D, 0xEF, 0xFF, 0xFF, 0x3C, 0xE7, 0x5D,
+ 0xEF, 0x7D, 0xEF,
+ 0xFB, 0xDE, 0xFB, 0xDE, 0x7D, 0xEF, 0xBA, 0xD6, 0xBE, 0xF7, 0xFF, 0xFF, 0xF7,
+ 0xBD, 0xF7, 0xBD,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xF7, 0xB6, 0xB5, 0x79,
+ 0xCE, 0xFF, 0xFF,
+ 0x3C, 0xE7, 0x75, 0xAD, 0xF7, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0x18, 0xC6, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0x79, 0xCE, 0xFF, 0xFF, 0x79, 0xCE, 0xFF, 0xFF, 0x79, 0xCE, 0xFF, 0xFF, 0x3C,
+ 0xE7, 0xB6, 0xB5,
+ 0x69, 0x4A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xF7, 0xB6, 0xB5, 0x9A,
+ 0xD6, 0xFF, 0xFF,
+ 0x79, 0xCE, 0xFF, 0xFF, 0x79, 0xCE, 0xBE, 0xF7, 0x9A, 0xD6, 0xDF, 0xFF, 0x96,
+ 0xB5, 0xB6, 0xB5,
+ 0xDF, 0xFF, 0xFF, 0xFF, 0xFB, 0xDE, 0x96, 0xB5, 0x5D, 0xEF, 0xFF, 0xFF, 0x59,
+ 0xCE, 0x75, 0xAD,
+ 0x1C, 0xE7, 0xFF, 0xFF, 0x59, 0xCE, 0x75, 0xAD, 0x1C, 0xE7, 0xFF, 0xFF, 0xBA,
+ 0xD6, 0xB6, 0xB5,
+ 0x7D, 0xEF, 0xFF, 0xFF, 0x18, 0xC6, 0x75, 0xAD, 0x5D, 0xEF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x9E, 0xF7,
+ 0xDB, 0xDE, 0xFF, 0xFF, 0xBE, 0xF7, 0x96, 0xB5, 0xDB, 0xDE, 0xFF, 0xFF, 0x7D,
+ 0xEF, 0x75, 0xAD,
+ 0x3C, 0xE7, 0xFF, 0xFF, 0x79, 0xCE, 0xFF, 0xFF, 0x9A, 0xD6, 0x96, 0xB5, 0xBE,
+ 0xF7, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x71,
+ 0x8C, 0x2C, 0x63,
+ 0x34, 0xA5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF
+};
+
+// logo reverse 11590UL + 1
+static const uint8_t aclogo[] = {
+ 0x00,
+ 0x10,
+ 0x60, 0x00,
+ 0x3C, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xBE, 0xFF, 0x3C, 0xF7, 0xFB, 0xF6, 0x1C, 0xF7, 0x5D, 0xF7, 0x7D, 0xFF,
+ 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D, 0xEF,
+ 0x96, 0xB5, 0x34, 0xA5, 0x55, 0xAD, 0x3C, 0xE7, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xFF, 0x79,
+ 0xF6,
+ 0x38, 0xF6, 0x59, 0xF6, 0x79, 0xF6, 0xDB, 0xF6, 0x1C, 0xF7, 0x5C, 0xF7, 0x5D,
+ 0xF7, 0x9D, 0xFF, 0x9E, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xBE, 0xFF, 0xFB, 0xF6, 0xDB, 0xF6, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xB6, 0xB5, 0xAE, 0x73, 0x2D, 0x6B, 0x30, 0x84, 0xB6, 0xB5,
+ 0xF7, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xFF, 0xDB, 0xF6, 0xB7, 0xF5, 0x55, 0xED,
+ 0x96, 0xED, 0x38, 0xF6, 0xBB, 0xF6, 0xFB, 0xF6, 0x1C, 0xF7, 0x3C, 0xF7, 0x7D,
+ 0xFF,
+ 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xDF, 0xFF, 0x3C, 0xF7, 0x59, 0xF6, 0xB7, 0xF5, 0x14, 0xED, 0xB3, 0xEC,
+ 0x72, 0xEC, 0x72, 0xEC, 0x72, 0xEC, 0xB3, 0xEC, 0x14, 0xED, 0x96, 0xF5, 0x79,
+ 0xF6,
+ 0x5D, 0xF7, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xFF, 0x5C, 0xF7, 0xF8, 0xF5, 0x31,
+ 0xEC,
+ 0xB3, 0xEC, 0xFB, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x9C, 0xAE, 0x7B, 0xEF,
+ 0x7B, 0x55, 0xAD, 0x34, 0xA5, 0x14, 0xA5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xDF, 0xFF, 0xBE, 0xFF, 0xFB, 0xF6, 0x55, 0xF5, 0x52, 0xEC, 0xB3, 0xEC, 0xB7,
+ 0xF5, 0x9A, 0xF6, 0xDB, 0xF6, 0x1B, 0xF7, 0x7D, 0xF7, 0xDF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xFF, 0x5D,
+ 0xFF,
+ 0xF7, 0xF5, 0x52, 0xEC, 0x0D, 0xE3, 0x4A, 0xDA, 0xE8, 0xD9, 0x87, 0xD9, 0x67,
+ 0xD9, 0x26, 0xD1, 0x26, 0xD1, 0x05, 0xD1, 0x05, 0xD1, 0x05, 0xD1, 0x06, 0xD1,
+ 0x26, 0xD1, 0x67, 0xD9, 0x87, 0xD9, 0xE9, 0xD9, 0x6A, 0xDA, 0x6E, 0xE3, 0x14,
+ 0xED,
+ 0xDB, 0xF6, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x7D, 0xFF, 0xB6, 0xF5, 0xAB, 0xE2, 0xE8, 0xD9, 0x11, 0xE4, 0xDB,
+ 0xFE,
+ 0x79, 0xCE, 0x10, 0x7C, 0x10, 0x84, 0xCF, 0x7B, 0x18, 0xC6, 0xBA, 0xD6, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xDF, 0xFF, 0x5D, 0xFF, 0x38, 0xF6, 0x31, 0xEC, 0xED, 0xE2, 0xF0, 0xEB, 0x96,
+ 0xF5,
+ 0xBA, 0xF6, 0xFB, 0xF6, 0x7D, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xFF, 0x1C, 0xF7,
+ 0x14, 0xED, 0xED, 0xE2, 0xC8, 0xD9, 0x46, 0xD9, 0x05, 0xD1, 0xC4, 0xD0, 0xA4,
+ 0xD0,
+ 0xA4, 0xD0, 0xA4, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC5, 0xD0, 0xC5, 0xD0, 0xC5,
+ 0xD0, 0xC5, 0xD0, 0xC5, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0,
+ 0xA4, 0xD0, 0xC5, 0xD0, 0x26, 0xD1, 0xA8, 0xD9, 0x2D, 0xE3, 0x79, 0xF6, 0xDF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xFF, 0xD3, 0xEC,
+ 0x05, 0xD1, 0xC4, 0xD0, 0x09, 0xDA, 0xD4, 0xEC, 0x38, 0xDE, 0xFB, 0xDE, 0x9A,
+ 0xD6,
+ 0x9E, 0xF7, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE,
+ 0xFF, 0x5D, 0xFF, 0x18, 0xF6, 0xAF, 0xE3, 0xE9, 0xD9, 0x8B, 0xE2, 0xD4, 0xEC,
+ 0x9A, 0xF6, 0x1C, 0xF7, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x7D, 0xFF, 0xF7,
+ 0xF5, 0x4E, 0xE3, 0xA8, 0xD9, 0x05, 0xD1, 0xC4, 0xD0, 0xA4, 0xD0, 0xC4, 0xD0,
+ 0xC5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xC5, 0xD0, 0xA4, 0xD0,
+ 0xA4, 0xD0, 0x09, 0xDA, 0x7A, 0xF6, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x79, 0xF6, 0x4A, 0xDA, 0x84, 0xD0, 0xA4, 0xD0, 0x26, 0xD9,
+ 0x4E, 0xE3, 0x9A, 0xF6, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE,
+ 0xFF,
+ 0x5D, 0xFF, 0x79, 0xF6, 0xF0, 0xEB, 0xA8, 0xD9, 0xA7, 0xD9, 0xCC, 0xE2, 0x96,
+ 0xED, 0xFB, 0xF6, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x5D,
+ 0xFF,
+ 0x96, 0xED, 0xAB, 0xE2, 0x26, 0xD9, 0xC4, 0xD0, 0xA4, 0xD0, 0xC4, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xC4, 0xD0, 0x83, 0xD0, 0xAF, 0xE3, 0x7D, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0xF5, 0xC8, 0xD9, 0xA4,
+ 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0xC4, 0xD0, 0xCC, 0xE2, 0xBB, 0xF6, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x9D, 0xFF, 0xFB, 0xF6, 0x14, 0xED, 0x4A, 0xDA, 0xE4, 0xD0, 0x46, 0xD9, 0xEC,
+ 0xE2,
+ 0x18, 0xF6, 0x5D, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x9E, 0xFF, 0x38, 0xF6, 0x0D, 0xE3, 0x06, 0xD1, 0xA4, 0xD0, 0xC4, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0xC4,
+ 0xD0, 0x31, 0xEC, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5C,
+ 0xFF,
+ 0x8F, 0xE3, 0xC4, 0xD0, 0xC4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0xC4,
+ 0xD0, 0x31, 0xE4, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF,
+ 0xFF, 0x5C, 0xFF, 0x59, 0xF6, 0xF0, 0xE3, 0x67, 0xD9, 0x63, 0xD0, 0xC4, 0xD0,
+ 0x8B, 0xDA, 0xD7, 0xF5, 0x5D, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3C, 0xFF, 0x92, 0xEC, 0xA8, 0xD9, 0xA4, 0xD0, 0xC4, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xC4, 0xD0, 0x87, 0xD9, 0x4E, 0xE3, 0x1C, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x9D, 0xFF, 0x79, 0xF6, 0xAF, 0xE3, 0x05, 0xD1, 0xA4, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0x46, 0xD9, 0xBA, 0xF6, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xDF, 0xFF, 0x1C, 0xF7, 0xB7, 0xF5, 0x2D, 0xE3, 0x26, 0xD9, 0x84, 0xD0, 0x63,
+ 0xD0, 0x87, 0xD9, 0x72, 0xEC, 0x1C, 0xF7, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0xFF, 0xD0, 0xE3, 0x05, 0xD1, 0x84,
+ 0xD0, 0xC5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xA8, 0xD9, 0xD3, 0xEC, 0x59, 0xF6, 0x1C,
+ 0xF7,
+ 0x5D, 0xFF, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D,
+ 0xFF, 0xDB, 0xF6, 0xF8, 0xF5, 0x31, 0xEC, 0xA8, 0xD9, 0xA4, 0xD0, 0xA4, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xC5, 0xD0, 0x63,
+ 0xD0,
+ 0x38, 0xF6, 0x9D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0xFF, 0x96, 0xED, 0x0D, 0xE3, 0xE5, 0xD0, 0x84,
+ 0xD0,
+ 0xA4, 0xD0, 0x83, 0xD0, 0xE9, 0xD9, 0x96, 0xED, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xFF, 0x92,
+ 0xEC,
+ 0x05, 0xD1, 0xA4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xC4, 0xD0,
+ 0xC4, 0xD0, 0xC4, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0x84,
+ 0xD0,
+ 0x84, 0xD0, 0x84, 0xD0, 0x84, 0xD0, 0x84, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0xA4,
+ 0xD0, 0xA4, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC5, 0xD0, 0xC4, 0xD0, 0xA4, 0xD0,
+ 0x26, 0xD9, 0xA8, 0xD9, 0xAB, 0xE2, 0xAF, 0xE3, 0x92, 0xEC, 0x76, 0xED, 0xF8,
+ 0xF5,
+ 0x39, 0xF6, 0x96, 0xED, 0x11, 0xEC, 0x29, 0xDA, 0xC4, 0xD0, 0x84, 0xD0, 0xA4,
+ 0xD0, 0xC5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0x63, 0xD0, 0x18, 0xF6, 0x5D, 0xF7, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xFF, 0xD7, 0xF5, 0x4E, 0xE3, 0x05, 0xD9,
+ 0x83, 0xD0, 0xA4, 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0x67, 0xD9, 0x76, 0xED, 0xBE,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFB, 0xF6, 0xAC, 0xE2, 0x63, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xC4, 0xD0, 0xC4, 0xD0, 0xA4, 0xD0, 0x84, 0xD0, 0x63, 0xD0, 0x84, 0xD0, 0xA4,
+ 0xD0, 0xE5, 0xD0, 0x26, 0xD9, 0x47, 0xD9, 0x87, 0xD9, 0xA8, 0xD9, 0xE8, 0xD9,
+ 0x09, 0xDA, 0x29, 0xDA, 0x29, 0xDA, 0x2A, 0xDA, 0x2A, 0xDA, 0x4A, 0xDA, 0x2A,
+ 0xDA,
+ 0x29, 0xDA, 0x09, 0xDA, 0xE9, 0xD9, 0xA8, 0xD9, 0x87, 0xD9, 0x46, 0xD9, 0x05,
+ 0xD1, 0xC4, 0xD0, 0x84, 0xD0, 0x63, 0xD0, 0x63, 0xD0, 0x63, 0xD0, 0x63, 0xD0,
+ 0x63, 0xD0, 0x43, 0xD0, 0x84, 0xD0, 0xE5, 0xD8, 0x84, 0xD0, 0x63, 0xD0, 0xA4,
+ 0xD0,
+ 0xC4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xC4, 0xD0, 0x84, 0xD0, 0x79, 0xF6,
+ 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xFF, 0x9A, 0xF6, 0xF0, 0xE3, 0x87,
+ 0xD9, 0x84, 0xD0, 0xA4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0x84, 0xD0,
+ 0x51, 0xE4, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x79, 0xF6, 0x2A, 0xDA, 0x63, 0xD0,
+ 0xE5, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0x05, 0xD1, 0x67, 0xD9, 0xE9, 0xD9, 0x6A,
+ 0xDA,
+ 0xCC, 0xE2, 0x2D, 0xE3, 0x8F, 0xE3, 0x31, 0xEC, 0xB3, 0xEC, 0x35, 0xED, 0xB7,
+ 0xF5, 0x18, 0xF6, 0x9A, 0xF6, 0xDB, 0xF6, 0x1C, 0xF7, 0x5C, 0xF7, 0x5D, 0xFF,
+ 0x5D, 0xFF, 0x5D, 0xFF, 0x5D, 0xFF, 0x1C, 0xF7, 0xFB, 0xF6, 0x9A, 0xF6, 0x18,
+ 0xF6,
+ 0xB7, 0xF5, 0x14, 0xED, 0x72, 0xEC, 0xD0, 0xE3, 0x4E, 0xE3, 0xCC, 0xE2, 0x4A,
+ 0xDA, 0xA8, 0xD9, 0x05, 0xD1, 0x83, 0xD0, 0x84, 0xD0, 0xA4, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0x84,
+ 0xD0, 0x29, 0xDA, 0x1C, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xFF, 0x55,
+ 0xED,
+ 0x8B, 0xDA, 0xA4, 0xD0, 0xA4, 0xD0, 0xC5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0x18, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5C,
+ 0xF7, 0x6E, 0xE3, 0x83, 0xD0, 0xA4, 0xD0, 0x87, 0xD9, 0x8F, 0xE3, 0xD3, 0xEC,
+ 0x96, 0xF5, 0x59, 0xF6, 0x1C, 0xF7, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xBE, 0xFF, 0xDB, 0xF6, 0xD7, 0xF5, 0xB3, 0xEC, 0x6E, 0xE3, 0x4A,
+ 0xDA, 0x05, 0xD1, 0x84, 0xD0, 0xC4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xA4, 0xD0, 0xC5, 0xD0, 0xF4, 0xEC, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFB, 0xF6, 0x11, 0xE4, 0x67, 0xD9, 0x83, 0xD0, 0xC4, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xC4, 0xD0, 0x18, 0xF6, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x38, 0xF6, 0xCC, 0xE2, 0xC4, 0xD0, 0x46,
+ 0xD9, 0x4E, 0xE3, 0x14, 0xED, 0x59, 0xF6, 0x3C, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xDF, 0xFF, 0x9A, 0xF6, 0xB3, 0xEC, 0xCC, 0xE2, 0xE5, 0xD0, 0xA4,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xC4, 0xD0, 0x84, 0xD0, 0x2D, 0xE3, 0x1C,
+ 0xF7,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xDB, 0xF6, 0x6E, 0xE3, 0xE5, 0xD0, 0x84, 0xD0, 0xC5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0x84, 0xD0, 0x11, 0xE4, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xBA, 0xF6, 0xD3, 0xEC, 0xAC, 0xDA, 0xE5, 0xD0, 0x84, 0xD0, 0x67, 0xD9, 0x6A,
+ 0xDA, 0xEC, 0xDA, 0x4E, 0xE3, 0x8F, 0xE3, 0xAF, 0xE3, 0xD0, 0xE3, 0xF0, 0xE3,
+ 0x11, 0xE4, 0x52, 0xEC, 0xB3, 0xEC, 0x35, 0xED, 0xD7, 0xF5, 0x9A, 0xF6, 0x7D,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xDB, 0xF6, 0x10, 0xEC, 0x46, 0xD9, 0xA4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0x84, 0xD0,
+ 0xAB, 0xDA, 0x9A, 0xF6, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xF6, 0x4E, 0xE3, 0xC5, 0xD0, 0xA4,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0x46, 0xD9, 0x31, 0xEC, 0x3C,
+ 0xF7,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xF6, 0xB7,
+ 0xF5,
+ 0xB3, 0xEC, 0x8F, 0xE3, 0x8B, 0xDA, 0xC8, 0xD9, 0x67, 0xD9, 0x46, 0xD9, 0x46,
+ 0xD9, 0x26, 0xD9, 0x26, 0xD9, 0xE5, 0xD0, 0xC4, 0xD0, 0xA4, 0xD8, 0xC4, 0xD0,
+ 0x25, 0xD9, 0xA7, 0xD9, 0x6A, 0xDA, 0x4E, 0xE3, 0xF4, 0xEC, 0xFB, 0xF6, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5C, 0xFF, 0x11, 0xE4, 0xA4,
+ 0xD0,
+ 0xC5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xA4,
+ 0xD0, 0x84, 0xD0, 0xAC, 0xE2, 0x39, 0xF6, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xFF, 0xF0,
+ 0xE3,
+ 0xE5, 0xD0, 0xA4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xA4, 0xD0, 0x26, 0xD1, 0xEC, 0xE2, 0x96, 0xF5, 0x9D, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D, 0xFF, 0xFB, 0xF6, 0x9A,
+ 0xF6,
+ 0x79, 0xF6, 0x59, 0xF6, 0x38, 0xF6, 0x38, 0xF6, 0x18, 0xF6, 0xD7, 0xF5, 0xB7,
+ 0xED, 0x96, 0xED, 0x55, 0xED, 0x14, 0xED, 0x51, 0xEC, 0x0D, 0xE3, 0x87, 0xD9,
+ 0x06, 0xD9, 0x29, 0xDA, 0x52, 0xEC, 0xDB, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x18, 0xF6, 0x87, 0xD9, 0xC4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xA4, 0xD0, 0xC4, 0xD0, 0x2E, 0xE3, 0x7A, 0xF6, 0xDF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xDE, 0xFF, 0xB7, 0xF5, 0x26, 0xD9, 0xA4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0x67, 0xD9,
+ 0x6A, 0xDA, 0x11, 0xEC, 0x18, 0xF6, 0x9D, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D,
+ 0xFF, 0x59, 0xF6, 0x72, 0xEC, 0x09, 0xDA, 0x84, 0xD0, 0xE5, 0xD0, 0x2D, 0xE3,
+ 0xBA, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x59, 0xF6, 0xC8, 0xD9, 0xC4, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xC4, 0xD0, 0x84, 0xD0, 0x66, 0xD9, 0x52, 0xEC, 0xFB,
+ 0xF6,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0xF7, 0xCC, 0xE2, 0x84, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xA4, 0xD0, 0xE5, 0xD0, 0x46, 0xD9, 0xC8, 0xD9,
+ 0x8B, 0xE2, 0xF0, 0xE3, 0x35, 0xED, 0x59, 0xF6, 0x3C, 0xF7, 0xBE, 0xFF, 0xDE,
+ 0xFF,
+ 0xDE, 0xFF, 0xDE, 0xFF, 0xDF, 0xFF, 0xDF, 0xFF, 0xDF, 0xFF, 0xDF, 0xFF, 0xDF,
+ 0xFF, 0xDF, 0xFF, 0xDF, 0xFF, 0xDF, 0xFF, 0xDE, 0xFF, 0xDE, 0xFF, 0xDE, 0xFF,
+ 0xBE, 0xFF, 0x5D, 0xF7, 0xBB, 0xF6, 0x18, 0xF6, 0x55, 0xED, 0x92, 0xEC, 0xAF,
+ 0xE3,
+ 0xEC, 0xE2, 0x2A, 0xDA, 0xC8, 0xD9, 0x87, 0xD9, 0x67, 0xD9, 0x05, 0xD1, 0xC4,
+ 0xD0, 0xA4, 0xD0, 0x84, 0xD0, 0x14, 0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x76,
+ 0xED, 0xE5, 0xD0, 0xC4, 0xD0, 0xC5, 0xD0, 0xA4, 0xD0, 0xC4, 0xD0, 0xAC, 0xE2,
+ 0x96, 0xF5, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xF6, 0xC4,
+ 0xD0, 0xC4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xA4, 0xD0, 0xC4, 0xD0, 0xC5, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0xA4,
+ 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0xC4, 0xD0, 0xE5, 0xD0, 0x05, 0xD1, 0x26, 0xD9,
+ 0x46, 0xD9, 0x67, 0xD9, 0xA8, 0xD9, 0xC8, 0xD9, 0x09, 0xDA, 0x4A, 0xDA, 0x6B,
+ 0xDA,
+ 0xAB, 0xE2, 0xAB, 0xE2, 0xAB, 0xE2, 0x8B, 0xE2, 0x6A, 0xDA, 0x4A, 0xDA, 0x09,
+ 0xDA, 0xC8, 0xD9, 0xA8, 0xD9, 0x67, 0xD9, 0x46, 0xD9, 0x26, 0xD9, 0x26, 0xD9,
+ 0x05, 0xD1, 0x05, 0xD1, 0xE5, 0xD0, 0xC4, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0xA4,
+ 0xD0,
+ 0xC4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xC5, 0xD0, 0x43, 0xD0, 0xB3, 0xEC, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xDF, 0xFF, 0x9A, 0xF6, 0xCC, 0xE2, 0x83, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0xE9,
+ 0xD9, 0xD3, 0xEC, 0x1C, 0xF7, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0x5D, 0xFF, 0x18, 0xF6, 0x63, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0x26, 0xD9, 0x8F, 0xE3, 0x76,
+ 0xED,
+ 0x92, 0xEC, 0xCC, 0xE2, 0x46, 0xD9, 0xC5, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC4,
+ 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0,
+ 0xC4, 0xD0, 0xC5, 0xD0, 0xC4, 0xD0, 0xC5, 0xD0, 0xC5, 0xD0, 0xC5, 0xD0, 0xC5,
+ 0xD0,
+ 0xC5, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC4,
+ 0xD0, 0xC4, 0xD0, 0xC4, 0xD0, 0xC5, 0xD0, 0xE5, 0xD0, 0xC5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xA4,
+ 0xD0,
+ 0x46, 0xD9, 0x96, 0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xFF, 0x9A, 0xF6, 0x4E, 0xE3, 0x84, 0xD0, 0x84,
+ 0xD0,
+ 0x87, 0xD9, 0x31, 0xEC, 0xDB, 0xF6, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D, 0xFF, 0x18, 0xF6, 0x63, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xC4, 0xD0, 0xA4, 0xD0, 0x26, 0xD9, 0x6E, 0xE3,
+ 0x59, 0xF6, 0x9E, 0xFF, 0xDF, 0xFF, 0xBE, 0xFF, 0x9D, 0xFF, 0x5D, 0xF7, 0xBA,
+ 0xF6,
+ 0x35, 0xED, 0x8F, 0xE3, 0xC8, 0xD9, 0xC4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xC5, 0xD0, 0xA4, 0xD0, 0x05, 0xD1, 0x52, 0xEC, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xFF, 0xF7, 0xF5, 0x8B, 0xDA,
+ 0xC4, 0xD0, 0x67, 0xD9, 0xF0, 0xE3, 0x9A, 0xF6, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xBA, 0xF6, 0xE5, 0xD8, 0xA4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0xC4, 0xD0, 0x4A,
+ 0xDA, 0x96, 0xED, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xFF, 0xD7, 0xF5, 0xCC, 0xE2, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0xA8, 0xD9, 0xB3, 0xEC, 0x7D, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xFF, 0xBA, 0xF6, 0xB3,
+ 0xEC, 0xE8, 0xD9, 0xE8, 0xD9, 0x51, 0xEC, 0xDB, 0xF6, 0xBE, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xF7, 0x6E, 0xE3, 0xA4, 0xD0, 0xC4, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0x84,
+ 0xD0,
+ 0x26, 0xD9, 0xAF, 0xE3, 0x9A, 0xF6, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xF6,
+ 0x87, 0xD9, 0xA4, 0xD0, 0xC4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xC5, 0xD0, 0xA4, 0xD0, 0xA4, 0xD0, 0x46, 0xD9, 0x0D, 0xE3, 0xF7,
+ 0xF5, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xFF, 0xBA,
+ 0xF6,
+ 0xB7, 0xF5, 0x4E, 0xE3, 0xCC, 0xE2, 0x14, 0xED, 0x5D, 0xFF, 0xDF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x9A,
+ 0xF6, 0x4A, 0xDA, 0x84, 0xD0, 0xC4, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xA4, 0xD0, 0x46, 0xD9, 0xB3, 0xEC, 0x7D, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xDF, 0xFF, 0xDB, 0xF6, 0x66, 0xD9, 0x83, 0xD0, 0xC4, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xC4, 0xD0, 0xA4, 0xD0, 0x84, 0xD0, 0xE5, 0xD0, 0xA8, 0xD9, 0xED,
+ 0xE2,
+ 0x76, 0xED, 0x9D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x5D, 0xF7,
+ 0xDB, 0xF6, 0x18, 0xF6, 0x72, 0xEC, 0x72, 0xEC, 0x59, 0xF6, 0x9E, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x38, 0xF6, 0x8B, 0xDA, 0xA4, 0xD0, 0xA4,
+ 0xD0, 0xC5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0x83, 0xD0, 0x6E, 0xE3, 0x5D, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xFF, 0xF4, 0xEC, 0x29,
+ 0xDA, 0xC4, 0xD0, 0x84, 0xD0, 0xA4, 0xD0, 0xC5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5,
+ 0xD0,
+ 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xE5, 0xD0, 0xC5, 0xD0, 0xC4,
+ 0xD0, 0xA4, 0xD0, 0x83, 0xD0, 0xA4, 0xD0, 0x06, 0xD1, 0xC8, 0xD9, 0xAB, 0xDA,
+ 0x10, 0xE4, 0x59, 0xF6, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xFF, 0x7D,
+ 0xFF, 0x3C, 0xF7, 0x59, 0xF6, 0xB6, 0xF5, 0x39, 0xF6, 0x9E, 0xFF, 0xDF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0x9A, 0xF6, 0x6E, 0xE3, 0x67, 0xD9, 0x84, 0xD0, 0xA4, 0xD0, 0xC5, 0xD0, 0x63,
+ 0xD0, 0x10, 0xE4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xDE, 0xFF, 0x79, 0xF6, 0xF0, 0xE3, 0x8B, 0xDA, 0x87, 0xD9, 0xC5,
+ 0xD0, 0x83, 0xD0, 0x63, 0xD0, 0x83, 0xD0, 0x84, 0xD0, 0x84, 0xD0, 0xA4, 0xD0,
+ 0xA4, 0xD0, 0xA4, 0xD0, 0x84, 0xD0, 0x84, 0xD0, 0x83, 0xD0, 0x63, 0xD0, 0x63,
+ 0xD0,
+ 0x84, 0xD0, 0xE5, 0xD0, 0x67, 0xD9, 0x09, 0xDA, 0xAB, 0xDA, 0x6E, 0xE3, 0x93,
+ 0xEC, 0x39, 0xF6, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xBE, 0xFF, 0x7D, 0xF7, 0xFB, 0xF6, 0xDB, 0xF6, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xFF, 0x55, 0xED, 0x2D,
+ 0xE3,
+ 0x87, 0xD9, 0x84, 0xD0, 0x22, 0xD0, 0x4A, 0xDA, 0x59, 0xF6, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0x3C, 0xFF, 0xB7, 0xF5, 0x72, 0xEC, 0xAF, 0xE3, 0x2D, 0xE3, 0xAB, 0xDA, 0x4A,
+ 0xDA, 0x29, 0xDA, 0x09, 0xDA, 0x09, 0xDA, 0x09, 0xDA, 0x2A, 0xDA, 0x6A, 0xDA,
+ 0xAB, 0xDA, 0x0D, 0xE3, 0x6E, 0xE3, 0xF0, 0xE3, 0x72, 0xEC, 0x55, 0xED, 0x79,
+ 0xF6,
+ 0x7D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xFF, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xFF, 0x96, 0xF5, 0xF0, 0xE3, 0x6B, 0xDA, 0x05,
+ 0xD9,
+ 0x29, 0xDA, 0xD3, 0xEC, 0x1C, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xBE, 0xFF, 0x3C, 0xF7, 0xBA, 0xF6, 0x79, 0xF6, 0x59, 0xF6, 0x39, 0xF6, 0x59,
+ 0xF6, 0x7A, 0xF6, 0xBA, 0xF6, 0x1C, 0xF7, 0x9E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xDE, 0xFF, 0xDB, 0xF6, 0x55, 0xED, 0x31, 0xEC, 0x10, 0xE4, 0x72, 0xEC, 0x14,
+ 0xED,
+ 0x18, 0xF6, 0x5C, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x3C, 0xF7, 0x38, 0xF6, 0x18, 0xF6, 0x7A, 0xF6, 0xDB, 0xF6, 0x7D, 0xF7, 0xDF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xDF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xF7,
+ 0x9E, 0xFF, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF,
+ 0xFF,
+ 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE,
+ 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDE, 0xF7, 0xDF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xDE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xDE, 0xF7, 0x79, 0xCE, 0x55, 0xAD, 0x55, 0xAD, 0x55, 0xAD, 0x17, 0xBE, 0xBE,
+ 0xF7,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xEF, 0x96, 0xB5, 0x79, 0xCE, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xBE, 0xF7, 0x75, 0xAD, 0xDA, 0xD6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xDE, 0xF7, 0xB6, 0xB5, 0xD7, 0xBD, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0x7D, 0xEF, 0xD6, 0xB5, 0x55, 0xAD, 0x55, 0xAD, 0x96, 0xB5, 0xDB, 0xDE, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xD6, 0x96, 0xB5, 0x55, 0xAD, 0x55, 0xAD,
+ 0xD7, 0xBD, 0x7D, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xD6, 0x55, 0xAD, 0x7D,
+ 0xEF,
+ 0xFF, 0xFF, 0x9D, 0xEF, 0x55, 0xAD, 0xDB, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xBE, 0xF7, 0x96, 0xB5, 0x99, 0xCE, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D, 0xEF, 0x55, 0xAD, 0xBA, 0xD6, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0xDF, 0x34, 0xA5, 0x55, 0xAD,
+ 0x55, 0xAD, 0x55, 0xAD, 0x59, 0xCE, 0xBE, 0xF7, 0xFF, 0xFF, 0xBE, 0xF7, 0x38,
+ 0xC6,
+ 0x55, 0xAD, 0x55, 0xAD, 0x55, 0xAD, 0xF7, 0xBD, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x9E, 0xF7, 0x79, 0xCE, 0x45, 0x29, 0x04, 0x21, 0x04, 0x21,
+ 0x04, 0x21, 0x65, 0x29, 0xB2, 0x94, 0xFF, 0xFF, 0xFF, 0xFF, 0x38, 0xC6, 0x28,
+ 0x42,
+ 0xB2, 0x94, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xDE, 0x49, 0x4A, 0x14, 0xA5, 0xBE,
+ 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0xEF, 0x08, 0x42, 0x69, 0x4A,
+ 0x9E, 0xF7, 0xFF, 0xFF, 0x7D, 0xEF, 0x71, 0x8C, 0x04, 0x21, 0x24, 0x21, 0x04,
+ 0x21,
+ 0x04, 0x21, 0xEB, 0x5A, 0xDB, 0xDE, 0xFF, 0xFF, 0xBA, 0xD6, 0xAA, 0x52, 0x04,
+ 0x21, 0x04, 0x21, 0x24, 0x21, 0x04, 0x21, 0xB2, 0x94, 0x7D, 0xEF, 0xBE, 0xF7,
+ 0x71, 0x8C, 0x86, 0x31, 0xD2, 0x94, 0xDE, 0xF7, 0xDB, 0xDE, 0x86, 0x31, 0xF3,
+ 0x9C,
+ 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0xE7, 0xAA, 0x52, 0x92, 0x94, 0x9E, 0xF7,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xF7, 0x13,
+ 0x9D,
+ 0x65, 0x29, 0x4D, 0x6B, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x96,
+ 0xB5, 0xC3, 0x18, 0xE4, 0x20, 0x24, 0x21, 0x04, 0x21, 0x24, 0x21, 0x13, 0x9D,
+ 0xFF, 0xFF, 0x14, 0xA5, 0x86, 0x31, 0x04, 0x21, 0x04, 0x21, 0x04, 0x21, 0x24,
+ 0x21,
+ 0x38, 0xC6, 0x5D, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0xE7, 0xD7, 0xBD, 0x24,
+ 0x21, 0x96, 0xB5, 0xBA, 0xD6, 0xD3, 0x9C, 0x04, 0x21, 0x8E, 0x73, 0xDF, 0xFF,
+ 0xFF, 0xFF, 0x18, 0xC6, 0x65, 0x29, 0x51, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B,
+ 0xDF,
+ 0xA6, 0x31, 0xD2, 0x94, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D,
+ 0xEF, 0x66, 0x31, 0xC7, 0x39, 0xBE, 0xF7, 0xFF, 0xFF, 0x1C, 0xE7, 0xEC, 0x62,
+ 0xE7, 0x39, 0xBA, 0xD6, 0xBA, 0xD6, 0xEF, 0x7B, 0xE7, 0x39, 0xD7, 0xBD, 0xFF,
+ 0xFF,
+ 0xD7, 0xBD, 0x65, 0x29, 0x10, 0x84, 0xDA, 0xD6, 0x9A, 0xD6, 0xA6, 0x31, 0x2C,
+ 0x63, 0x3C, 0xE7, 0xDE, 0xF7, 0x10, 0x84, 0x61, 0x08, 0x86, 0x31, 0x3C, 0xE7,
+ 0xDA, 0xD6, 0xA3, 0x18, 0xB2, 0x94, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0xE7, 0x08,
+ 0x42, 0x30, 0x84, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x9D, 0xEF, 0x8A, 0x52, 0x41, 0x08, 0x45, 0x29, 0x9D, 0xEF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0xAD, 0x04, 0x21, 0xD2, 0x94, 0xDA, 0xD6, 0x34,
+ 0xA5, 0x65, 0x29, 0x71, 0x8C, 0xFF, 0xFF, 0xAE, 0x73, 0x04, 0x21, 0x13, 0x9D,
+ 0xBA, 0xD6, 0x75, 0xAD, 0xA6, 0x31, 0xB6, 0xB5, 0xBA, 0xD6, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0x1B, 0xDF, 0xD6, 0xB5, 0x24, 0x21, 0x96, 0xB5, 0x7D, 0xEF, 0x5D, 0xEF, 0xD7,
+ 0xBD, 0x9A, 0xD6, 0xFF, 0xFF, 0xFF, 0xFF, 0x38, 0xC6, 0x66, 0x31, 0x51, 0x8C,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0xE7, 0xA6, 0x31, 0xD3, 0x9C, 0xBE, 0xF7, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x9D, 0xEF, 0x86, 0x31, 0xE7, 0x39, 0xBE, 0xF7, 0xFF,
+ 0xFF, 0x3C, 0xE7, 0xCB, 0x5A, 0x28, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xDE,
+ 0x18, 0xC6, 0x7D, 0xEF, 0xFF, 0xFF, 0xD6, 0xB5, 0x24, 0x21, 0x14, 0xA5, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xE7, 0x39, 0xEC, 0x62, 0x5C, 0xE7, 0xDF, 0xFF, 0x30, 0x84, 0x41,
+ 0x08, 0xA3, 0x18, 0x55, 0xAD, 0xBA, 0xD6, 0xA3, 0x18, 0xB2, 0x94, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0x3C, 0xE7, 0x08, 0x42, 0x30, 0x84, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0xE7, 0x04, 0x21, 0x49, 0x4A,
+ 0xE4, 0x20, 0x59, 0xCE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0xAD, 0x24,
+ 0x21,
+ 0xB6, 0xB5, 0xFF, 0xFF, 0x38, 0xC6, 0x86, 0x31, 0x51, 0x8C, 0xFF, 0xFF, 0xAE,
+ 0x73, 0xA3, 0x18, 0x34, 0xA5, 0xBE, 0xF7, 0xDE, 0xF7, 0xF7, 0xBD, 0x7D, 0xEF,
+ 0xDE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xF7, 0x79, 0xCE, 0x24, 0x21, 0x24,
+ 0x21,
+ 0x6D, 0x6B, 0x79, 0xCE, 0x3C, 0xE7, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x38,
+ 0xC6, 0x86, 0x31, 0x51, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0xE7, 0xA6, 0x31,
+ 0xD3, 0x9C, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9D, 0xEF, 0x86,
+ 0x31,
+ 0xE7, 0x39, 0xDE, 0xF7, 0xFF, 0xFF, 0x3C, 0xE7, 0xCB, 0x5A, 0x28, 0x42, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xDE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0xBD,
+ 0x24, 0x21, 0x14, 0xA5, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x39, 0x0C, 0x63, 0x5C,
+ 0xE7,
+ 0xDF, 0xFF, 0x30, 0x84, 0x61, 0x08, 0x04, 0x21, 0x08, 0x42, 0x38, 0xC6, 0xC3,
+ 0x18, 0xB2, 0x94, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5C, 0xE7, 0x08, 0x42, 0x51,
+ 0x8C,
+ 0xBE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xB6,
+ 0xB5, 0x24, 0x21, 0x96, 0xB5, 0x04, 0x21, 0xEF, 0x7B, 0xDF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x75, 0xAD, 0x24, 0x21, 0x14, 0xA5, 0x3C, 0xE7, 0x55, 0xAD, 0x28,
+ 0x42,
+ 0xD3, 0x9C, 0xFF, 0xFF, 0x34, 0xA5, 0x66, 0x31, 0xC3, 0x18, 0x8E, 0x73, 0x58,
+ 0xC6, 0x5C, 0xE7, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xDE, 0xF7, 0x38, 0xC6, 0xEB, 0x5A, 0x45, 0x29, 0x24, 0x21, 0x4D, 0x6B, 0xFB,
+ 0xDE,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x38, 0xC6, 0x86, 0x31, 0x51, 0x8C, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x1C, 0xE7, 0xA6, 0x31, 0xD3, 0x9C, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x9D, 0xEF, 0x86, 0x31, 0xE7, 0x39, 0xDE, 0xF7, 0xFF, 0xFF, 0x3C,
+ 0xE7,
+ 0xCB, 0x5A, 0x28, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xD7, 0xBD, 0x24, 0x21, 0x14, 0xA5, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xE7, 0x39, 0x0C, 0x63, 0x5C, 0xE7, 0xDF, 0xFF, 0x30, 0x84, 0xC3, 0x18, 0x92,
+ 0x94,
+ 0x45, 0x29, 0xF3, 0x9C, 0xC3, 0x18, 0xB2, 0x94, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x5C, 0xE7, 0x08, 0x42, 0x51, 0x8C, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xBE, 0xF7, 0x0C, 0x63, 0x65, 0x29, 0xDA, 0xD6, 0x49, 0x4A, 0xE7,
+ 0x39, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x75, 0xAD, 0x20, 0x00, 0xC3, 0x18,
+ 0x25, 0x29, 0xE3, 0x18, 0xEC, 0x62, 0xDB, 0xDE, 0xFF, 0xFF, 0xBE, 0xF7, 0xF7,
+ 0xBD,
+ 0x69, 0x4A, 0x24, 0x21, 0xC3, 0x18, 0x6D, 0x6B, 0x5C, 0xE7, 0xDF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xBE, 0xF7, 0x59, 0xCE,
+ 0xCB, 0x5A, 0x82, 0x10, 0x10, 0x84, 0xFF, 0xFF, 0xFF, 0xFF, 0x38, 0xC6, 0x86,
+ 0x31,
+ 0x51, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0xE7, 0xA6, 0x31, 0xD3, 0x9C, 0xBE,
+ 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9D, 0xEF, 0x86, 0x31, 0xE7, 0x39,
+ 0xDE, 0xF7, 0xFF, 0xFF, 0x3C, 0xE7, 0xCB, 0x5A, 0x28, 0x42, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xD7, 0xBD, 0x24, 0x21, 0x14,
+ 0xA5, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x39, 0xEC, 0x62, 0x5C, 0xE7, 0xDF, 0xFF,
+ 0x30, 0x84, 0xE3, 0x18, 0x79, 0xCE, 0x45, 0x29, 0xA6, 0x31, 0xA2, 0x10, 0xB2,
+ 0x94,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5C, 0xE7, 0x08, 0x42, 0x51, 0x8C, 0xBE, 0xF7,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7D, 0xEF, 0x45, 0x29, 0x08,
+ 0x42,
+ 0xF7, 0xBD, 0x8E, 0x73, 0xA6, 0x31, 0x1C, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0x55,
+ 0xAD, 0x82, 0x10, 0x6D, 0x6B, 0x14, 0xA5, 0x8E, 0x73, 0xC7, 0x39, 0x54, 0xA5,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9D, 0xEF, 0x18, 0xC6, 0x8A, 0x52, 0x82,
+ 0x10,
+ 0xF7, 0xBD, 0x3C, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0x9E, 0xF7, 0x3C, 0xE7, 0xF7,
+ 0xBD, 0x9E, 0xF7, 0xFF, 0xFF, 0xD6, 0xB5, 0xE3, 0x18, 0x8E, 0x73, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x38, 0xC6, 0x66, 0x31, 0x51, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B,
+ 0xDF,
+ 0xA6, 0x31, 0xF3, 0x9C, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9D,
+ 0xEF, 0x86, 0x31, 0xE7, 0x39, 0xBE, 0xF7, 0xFF, 0xFF, 0x3C, 0xE7, 0xCB, 0x5A,
+ 0x28, 0x42, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xDE, 0xF7, 0xBD, 0x5C, 0xE7, 0xFF,
+ 0xFF,
+ 0xD6, 0xB5, 0x25, 0x29, 0x14, 0xA5, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x39, 0xEC,
+ 0x62, 0x5C, 0xE7, 0xDF, 0xFF, 0x30, 0x84, 0xC3, 0x18, 0x1C, 0xE7, 0x10, 0x84,
+ 0x41, 0x08, 0xA2, 0x10, 0xB2, 0x94, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3C, 0xE7, 0x28,
+ 0x42, 0x71, 0x8C, 0xDE, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x79, 0xCE, 0x82, 0x10, 0x82, 0x10, 0xE4, 0x20, 0xC3, 0x18, 0xA2, 0x10, 0xD3,
+ 0x9C,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0xAD, 0x25, 0x29, 0xD6, 0xB5, 0xFF, 0xFF, 0x38,
+ 0xC6, 0xC7, 0x39, 0x71, 0x8C, 0xFF, 0xFF, 0x99, 0xCE, 0xD7, 0xBD, 0x5D, 0xEF,
+ 0xFF, 0xFF, 0x9A, 0xD6, 0x65, 0x29, 0xB6, 0xB5, 0xFB, 0xDE, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0x9A, 0xD6, 0x75, 0xAD, 0x45, 0x29, 0x34, 0xA5, 0x99, 0xCE, 0xF3, 0x9C, 0xC3,
+ 0x18, 0x8E, 0x73, 0xFF, 0xFF, 0xFF, 0xFF, 0x18, 0xC6, 0x66, 0x31, 0x51, 0x8C,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0xDF, 0xC7, 0x39, 0x10, 0x84, 0x59, 0xCE, 0x79,
+ 0xCE,
+ 0x58, 0xC6, 0xBE, 0xF7, 0x9D, 0xEF, 0x86, 0x31, 0xC7, 0x39, 0xBE, 0xF7, 0xFF,
+ 0xFF, 0x1C, 0xE7, 0xCB, 0x5A, 0xC7, 0x39, 0x9A, 0xD6, 0x79, 0xCE, 0xAE, 0x73,
+ 0x86, 0x31, 0xB6, 0xB5, 0xFF, 0xFF, 0xB6, 0xB5, 0x45, 0x29, 0x10, 0x84, 0x99,
+ 0xCE,
+ 0x79, 0xCE, 0x86, 0x31, 0x0C, 0x63, 0x3C, 0xE7, 0xDF, 0xFF, 0x30, 0x84, 0xC3,
+ 0x18, 0x7D, 0xEF, 0xDB, 0xDE, 0x04, 0x21, 0xA2, 0x10, 0xB2, 0x94, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0x3C, 0xE7, 0x29, 0x4A, 0x8E, 0x73, 0x59, 0xCE, 0x79, 0xCE, 0x38,
+ 0xC6, 0x9E, 0xF7, 0xDE, 0xF7, 0xCF, 0x7B, 0xA3, 0x18, 0xAE, 0x73, 0x10, 0x84,
+ 0x8E, 0x73, 0x04, 0x21, 0xAA, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0x75, 0xAD, 0xE4,
+ 0x20,
+ 0xB2, 0x94, 0x9A, 0xD6, 0x14, 0xA5, 0x45, 0x29, 0x71, 0x8C, 0xFF, 0xFF, 0x6D,
+ 0x6B, 0xA2, 0x10, 0xB2, 0x94, 0x79, 0xCE, 0x96, 0xB5, 0x24, 0x21, 0xB6, 0xB5,
+ 0xFB, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0x5C, 0xE7, 0x18, 0xC6, 0xE3, 0x18, 0x45,
+ 0x29,
+ 0xA6, 0x31, 0x24, 0x21, 0xC3, 0x18, 0xD3, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0x17,
+ 0xBE, 0x65, 0x29, 0x30, 0x84, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xDE, 0x86, 0x31,
+ 0xC3, 0x18, 0x66, 0x31, 0x66, 0x31, 0xC7, 0x39, 0xFB, 0xDE, 0x5D, 0xEF, 0x86,
+ 0x31,
+ 0xE7, 0x39, 0x9E, 0xF7, 0xFF, 0xFF, 0x5D, 0xEF, 0x10, 0x84, 0x82, 0x10, 0xC7,
+ 0x39, 0xA6, 0x31, 0xE4, 0x20, 0x49, 0x4A, 0x9A, 0xD6, 0xFF, 0xFF, 0x79, 0xCE,
+ 0x08, 0x42, 0x04, 0x21, 0x86, 0x31, 0xC7, 0x39, 0x82, 0x10, 0x30, 0x84, 0x7D,
+ 0xEF,
+ 0xBE, 0xF7, 0x10, 0x84, 0xC3, 0x18, 0x5C, 0xE7, 0x7D, 0xEF, 0x8E, 0x73, 0xC3,
+ 0x18, 0xB2, 0x94, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1C, 0xE7, 0x08, 0x42, 0xA2,
+ 0x10,
+ 0x66, 0x31, 0x66, 0x31, 0xA6, 0x31, 0x9A, 0xD6, 0x7D, 0xEF, 0xA7, 0x39, 0xE8,
+ 0x41, 0x5D, 0xEF, 0xFF, 0xFF, 0x5D, 0xEF, 0x4D, 0x6B, 0x86, 0x31, 0x3C, 0xE7,
+ 0xFF, 0xFF, 0x54, 0xA5, 0x00, 0x00, 0x04, 0x21, 0xA7, 0x39, 0x04, 0x21, 0xE3,
+ 0x18,
+ 0x14, 0xA5, 0xFF, 0xFF, 0xD3, 0x9C, 0xC3, 0x18, 0x24, 0x21, 0xA6, 0x31, 0x65,
+ 0x29, 0xE3, 0x18, 0x18, 0xC6, 0x5D, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x5D, 0xEF, 0x92, 0x94, 0x6D, 0x6B, 0x6D, 0x6B, 0x6D, 0x6B, 0x92, 0x94, 0x5C,
+ 0xE7,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xDB, 0xDE, 0x51, 0x8C, 0xD6, 0xB5, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x5C, 0xE7, 0x51, 0x8C, 0x4D, 0x6B, 0x4D, 0x6B, 0x4D, 0x6B, 0x8E, 0x73,
+ 0x1C, 0xE7, 0x7D, 0xEF, 0x92, 0x94, 0xB2, 0x94, 0xBE, 0xF7, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xBA, 0xD6, 0xCF, 0x7B, 0x6D, 0x6B, 0x6D, 0x6B, 0x8E, 0x73, 0x96, 0xB5, 0xDF,
+ 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x55, 0xAD, 0x8E, 0x73, 0x6D, 0x6B, 0x6D, 0x6B,
+ 0xCF, 0x7B, 0xDB, 0xDE, 0xFF, 0xFF, 0xDE, 0xF7, 0xD7, 0xBD, 0xEF, 0x7B, 0x7D,
+ 0xEF,
+ 0xDF, 0xFF, 0x9A, 0xD6, 0x10, 0x84, 0x18, 0xC6, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x7D, 0xEF, 0x92, 0x94, 0x4D, 0x6B, 0x4D, 0x6B, 0x4D, 0x6B, 0x6D, 0x6B, 0xDB,
+ 0xDE,
+ 0x9D, 0xEF, 0x30, 0x84, 0x55, 0xAD, 0xBE, 0xF7, 0xFF, 0xFF, 0xBE, 0xF7, 0xF7,
+ 0xBD, 0x30, 0x84, 0x1B, 0xDF, 0xDF, 0xFF, 0x59, 0xCE, 0x4D, 0x6B, 0x6D, 0x6B,
+ 0x6D, 0x6B, 0x6D, 0x6B, 0xB2, 0x94, 0x1C, 0xE7, 0xFF, 0xFF, 0x5C, 0xE7, 0x92,
+ 0x94,
+ 0x6D, 0x6B, 0x6D, 0x6B, 0x6D, 0x6B, 0x92, 0x94, 0x5D, 0xEF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00
+};
diff --git a/driver/public/mikroe/oledc_ssd1351/inc/oled_display.h b/driver/public/mikroe/oledc_ssd1351/inc/oled_display.h
new file mode 100644
index 00000000..ea7a6543
--- /dev/null
+++ b/driver/public/mikroe/oledc_ssd1351/inc/oled_display.h
@@ -0,0 +1,89 @@
+/***************************************************************************//**
+ * @file oled_display.h
+ * @brief OLED Driver API interface
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#ifndef OLED_DISPLAY_H
+#define OLED_DISPLAY_H
+
+#include
+#include "sl_status.h"
+
+#include "mikroe_ssd1351.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct oled_display_driver_api {
+ sl_status_t (*init)(void);
+ sl_status_t (*draw_pixel)(int16_t x, int16_t y, uint16_t color);
+ uint16_t (*get_raw_pixel)(int16_t x, int16_t y);
+ sl_status_t (*fill_screen)(uint16_t color);
+ sl_status_t (*update_display)(void);
+ sl_status_t (*set_invert_color)(void);
+ sl_status_t (*set_normal_color)(void);
+ sl_status_t (*set_contrast)(uint8_t);
+ sl_status_t (*scroll_right)(uint8_t, uint8_t);
+ sl_status_t (*scroll_left)(uint8_t, uint8_t);
+ sl_status_t (*scroll_diag_right)(uint8_t, uint8_t);
+ sl_status_t (*scroll_diag_left)(uint8_t, uint8_t);
+ sl_status_t (*stop_scroll)(void);
+ sl_status_t (*enable_display)(bool);
+} oled_display_driver_api_t;
+
+/**
+ * General memory LCD data structure.
+ */
+typedef struct oled_display {
+ unsigned short width; ///< Display pixel width
+ unsigned short height; ///< Display pixel height
+ const oled_display_driver_api_t *driver;
+} oled_display_t;
+
+/**************************************************************************//**
+ * @brief
+ * Initialization function for the SSD1351 device driver.
+ *
+ * @return
+ * If all operations completed sucessfully SL_STATUS_OK is returned. On
+ * failure a different status code is returned specifying the error.
+ *****************************************************************************/
+sl_status_t oled_display_init(void);
+
+const oled_display_t *oled_display_get(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/driver/public/mikroe/oledc_ssd1351/src/mikroe_ssd1351.c b/driver/public/mikroe/oledc_ssd1351/src/mikroe_ssd1351.c
new file mode 100644
index 00000000..0cf8b7ad
--- /dev/null
+++ b/driver/public/mikroe/oledc_ssd1351/src/mikroe_ssd1351.c
@@ -0,0 +1,209 @@
+#include "mikroe_ssd1351.h"
+#include "mikroe_ssd1351_config.h"
+#include "third_party_hw_drivers_helpers.h"
+#include "stdio.h"
+
+static oledc_t oledc;
+static oledc_cfg_t oledc_cfg;
+static bool initialized = false;
+
+// -----------------------------------------------------------------------------
+// Public Function Definition
+// -----------------------------------------------------------------------------
+
+/***************************************************************************//**
+ * Initialization function.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_init(SPIDRV_Handle_t spi_instance)
+{
+ if (NULL == spi_instance) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ THIRD_PARTY_HW_DRV_RETCODE_INIT();
+
+ // Configure default spi instance
+ oledc.spi.handle = spi_instance;
+
+ // Call basic setup functions
+ oledc_cfg_setup(&oledc_cfg);
+ oledc_cfg.dc = hal_gpio_pin_name(SSD1351_DC_PORT, SSD1351_DC_PIN);
+ oledc_cfg.en = hal_gpio_pin_name(SSD1351_EN_PORT, SSD1351_EN_PIN);
+ oledc_cfg.rw = hal_gpio_pin_name(SSD1351_RW_PORT, SSD1351_RW_PIN);
+
+#if defined(SSD1351_RST_PORT) && defined(SSD1351_RST_PIN)
+ oledc_cfg.rst = hal_gpio_pin_name(SSD1351_RST_PORT, SSD1351_RST_PIN);
+#endif
+
+ THIRD_PARTY_HW_DRV_RETCODE_TEST(oledc_init(&oledc, &oledc_cfg));
+
+ initialized = true;
+ return THIRD_PARTY_HW_DRV_RETCODE_VALUE;
+}
+
+/***************************************************************************//**
+ * This function sets the SPI instance used by platform functions.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_set_spi_instance(SPIDRV_Handle_t spi_instance)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ if (NULL == spi_instance) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+ oledc.spi.handle = spi_instance;
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Default Configuration function.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_default_cfg(void)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ oledc_default_cfg(&oledc);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Enable/Disable display.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_enable(bool state)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ oledc_enable(&oledc, state);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Hardware Reset.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_reset(void)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ oledc_reset(&oledc);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Command Send with more argument.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_more_arg_commands(uint8_t command,
+ uint8_t *args,
+ uint16_t args_len)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ oledc_more_arg_commands(&oledc, command, args, args_len);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Command Send with one argument.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_one_arg_commands(uint8_t command, uint8_t args)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ oledc_one_arg_commands(&oledc, command, args);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Fill Screen.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_fill_screen(uint16_t color)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ oledc_fill_screen(&oledc, color);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Draw Rectangle.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_rectangle(uint8_t col_off,
+ uint8_t row_off,
+ uint8_t col_end,
+ uint8_t row_end,
+ uint16_t color)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ oledc_rectangle(&oledc, col_off, row_off, col_end, row_end, color);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Draw BMP Image.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_image(const uint8_t *img,
+ uint8_t col_off,
+ uint8_t row_off)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ oledc_image(&oledc, img, col_off, row_off);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Draw Text.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_text(uint8_t *text, uint16_t x, uint16_t y)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ oledc_text(&oledc, text, x, y);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Font Setup.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_set_font(const uint8_t *font_s, uint16_t color)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ oledc_set_font(&oledc, font_s, color);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Set Contrast.
+ ******************************************************************************/
+sl_status_t mikroe_ssd1351_set_contrast(uint8_t contrast)
+{
+ if (!initialized) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+ uint8_t oledc_contrast[3] = { 0x8A, contrast, 0x8A };
+ oledc_more_arg_commands(&oledc, OLEDC_CONTRAST, oledc_contrast, 3);
+ return SL_STATUS_OK;
+}
diff --git a/driver/public/mikroe/oledc_ssd1351/src/oled_display.c b/driver/public/mikroe/oledc_ssd1351/src/oled_display.c
new file mode 100644
index 00000000..5ebd91b7
--- /dev/null
+++ b/driver/public/mikroe/oledc_ssd1351/src/oled_display.c
@@ -0,0 +1,166 @@
+/***************************************************************************//**
+ * @file oled_display.c
+ * @brief OLED Driver API interface
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#include
+#include "mikroe_ssd1351_config.h"
+#include "oled_display.h"
+
+#define FRAME_HEADER 6
+#define FRAME_BUFFER_SIZE SSD1351_DISPLAY_HEIGHT *SSD1351_DISPLAY_WIDTH \
+ *SSD1351_DISPLAY_COLOR / 8 + FRAME_HEADER
+
+/* This oled_frame_buffer is large enough to store one full frame. */
+static uint8_t oled_frame_buffer[18438];
+static oled_display_t oled_display_instance;
+
+/** Flag to monitor is this driver has been initialized. The
+ * oled_display_instance
+ * is only valid after initialized=true. */
+static bool initialized = false;
+// -----------------------------------------------------------------------------
+// Static Function Declarations
+// -----------------------------------------------------------------------------
+static sl_status_t driver_init(void);
+static sl_status_t draw_pixel(int16_t x, int16_t y, uint16_t color);
+static uint16_t get_raw_pixel(int16_t x, int16_t y);
+static sl_status_t enable_display(bool state);
+static sl_status_t set_contrast(uint8_t contrast);
+static sl_status_t fill_screen(uint16_t color);
+static sl_status_t update_display(void);
+
+// -----------------------------------------------------------------------------
+// Public Function Definition
+// -----------------------------------------------------------------------------
+static const oled_display_driver_api_t sl_memlcd_driver_api =
+{
+ .init = driver_init,
+ .draw_pixel = draw_pixel,
+ .get_raw_pixel = get_raw_pixel,
+ .fill_screen = fill_screen,
+ .update_display = update_display,
+ .enable_display = enable_display,
+ .set_invert_color = NULL,
+ .set_normal_color = NULL,
+ .set_contrast = set_contrast,
+ .scroll_right = NULL,
+ .scroll_left = NULL,
+ .scroll_diag_right = NULL,
+ .scroll_diag_left = NULL,
+ .stop_scroll = NULL,
+};
+
+sl_status_t oled_display_init(void)
+{
+ oled_display_instance.width = SSD1351_DISPLAY_WIDTH;
+ oled_display_instance.height = SSD1351_DISPLAY_HEIGHT;
+ oled_display_instance.driver = &sl_memlcd_driver_api;
+ oled_frame_buffer[0] = 0x00;
+ oled_frame_buffer[1] = 0x10;
+ oled_frame_buffer[2] = 0x60;
+ oled_frame_buffer[3] = 0x00;
+ oled_frame_buffer[4] = 0x60;
+ oled_frame_buffer[5] = 0x00;
+ initialized = true;
+ return SL_STATUS_OK;
+}
+
+const oled_display_t *oled_display_get(void)
+{
+ if (initialized) {
+ return &oled_display_instance;
+ } else {
+ return NULL;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Static Function Definition
+// -----------------------------------------------------------------------------
+static sl_status_t driver_init(void)
+{
+ return mikroe_ssd1351_default_cfg();
+}
+
+static sl_status_t draw_pixel(int16_t x, int16_t y, uint16_t color)
+{
+ if ((x > OLEDC_SCREEN_WIDTH) || (y > OLEDC_SCREEN_HEIGHT)) {
+ return SL_STATUS_FAIL;
+ }
+
+ size_t index = FRAME_HEADER + 2 * (y * SSD1351_DISPLAY_WIDTH + x);
+
+ oled_frame_buffer[index] = color >> 8;
+ oled_frame_buffer[index + 1] = color & 0x00FF;
+
+ return SL_STATUS_OK;
+}
+
+static uint16_t get_raw_pixel(int16_t x, int16_t y)
+{
+ uint8_t index = y * SSD1351_DISPLAY_WIDTH * 2 + x * 2 + FRAME_HEADER;
+ return (uint16_t)(oled_frame_buffer[index] << 8)
+ | oled_frame_buffer[index + 1];
+}
+
+static sl_status_t fill_screen(uint16_t color)
+{
+ oled_frame_buffer[0] = 0x00;
+ oled_frame_buffer[1] = 0x10;
+ oled_frame_buffer[2] = 0x60;
+ oled_frame_buffer[3] = 0x00;
+ oled_frame_buffer[4] = 0x60;
+ oled_frame_buffer[5] = 0x00;
+
+ /* Fill the display with the color of the glib_context_t */
+ for (size_t i = 0; i < 96 * 96; i++) {
+ oled_frame_buffer[FRAME_HEADER + i * 2] = color >> 8;
+ oled_frame_buffer[FRAME_HEADER + i * 2 + 1] = color & 0x00FF;
+ }
+ return SL_STATUS_OK;
+}
+
+static sl_status_t update_display(void)
+{
+ return mikroe_ssd1351_image(oled_frame_buffer, 0, 0);
+}
+
+static sl_status_t set_contrast(uint8_t contrast)
+{
+ return mikroe_ssd1351_set_contrast(contrast);
+}
+
+sl_status_t enable_display(bool state)
+{
+ return mikroe_ssd1351_enable(state);
+}
diff --git a/driver/public/mikroe/pressure3_dps310/inc/mikroe_dps310_i2c.h b/driver/public/mikroe/pressure3_dps310/inc/mikroe_dps310_i2c.h
new file mode 100644
index 00000000..86cd195f
--- /dev/null
+++ b/driver/public/mikroe/pressure3_dps310/inc/mikroe_dps310_i2c.h
@@ -0,0 +1,498 @@
+/***************************************************************************//**
+ * @file mikroe_dps310_i2c.h
+ * @brief SCL DPS310 Prototypes
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef MIKROE_PRESSURE3_H
+#define MIKROE_PRESSURE3_H
+
+#include "sl_status.h"
+#include "drv_digital_out.h"
+#include "drv_digital_in.h"
+#include "drv_i2c_master.h"
+
+// -------------------------------------------------------------- PUBLIC MACROS
+
+/**
+ * \defgroup macros Macros
+ * \{
+ */
+
+/** \} */
+
+/**
+ * \defgroup configuration_register Configuration Registers
+ * \{
+ */
+#define MIKROE_PRESSURE3_I2C_ADDRESS 0x76
+#define MIKROE_PRESSURE3_REG_PSR_B2 0x00
+#define MIKROE_PRESSURE3_REG_PSR_B1 0x01
+#define MIKROE_PRESSURE3_REG_PSR_B0 0x02
+#define MIKROE_PRESSURE3_REG_TMP_B2 0x03
+#define MIKROE_PRESSURE3_REG_TMP_B1 0x04
+#define MIKROE_PRESSURE3_REG_TMP_B0 0x05
+#define MIKROE_PRESSURE3_REG_PRS_CFG 0x06
+#define MIKROE_PRESSURE3_REG_TMP_CFG 0x07
+#define MIKROE_PRESSURE3_REG_MEAS_CFG 0x08
+#define MIKROE_PRESSURE3_REG_CFG_REG 0x09
+#define MIKROE_PRESSURE3_REG_INT_STS 0x0A
+#define MIKROE_PRESSURE3_REG_FIFO_STS 0x0B
+#define MIKROE_PRESSURE3_REG_RESET 0x0C
+#define MIKROE_PRESSURE3_REG_PRODUCT_ID 0x0D
+#define MIKROE_PRESSURE3_REG_COEF_C0_MBS 0x10
+#define MIKROE_PRESSURE3_REG_COEF_C0_LBS_C1_MBS 0x11
+#define MIKROE_PRESSURE3_REG_COEF_C1_LBS 0x12
+#define MIKROE_PRESSURE3_REG_COEF_C00_MBS 0x13
+#define MIKROE_PRESSURE3_REG_COEF_C00_LSB 0x14
+#define MIKROE_PRESSURE3_REG_COEF_C00_XLSB_C10_MSB 0x15
+#define MIKROE_PRESSURE3_REG_COEF_C10_LSB 0x16
+#define MIKROE_PRESSURE3_REG_COEF_C10_XLSB 0x17
+#define MIKROE_PRESSURE3_REG_COEF_C01_MSB 0x18
+#define MIKROE_PRESSURE3_REG_COEF_C01_LSB 0x19
+#define MIKROE_PRESSURE3_REG_COEF_C11_MSB 0x1A
+#define MIKROE_PRESSURE3_REG_COEF_C11_LSB 0x1B
+#define MIKROE_PRESSURE3_REG_COEF_C20_MSB 0x1C
+#define MIKROE_PRESSURE3_REG_COEF_C20_LSB 0x1D
+#define MIKROE_PRESSURE3_REG_COEF_C21_MSB 0x1E
+#define MIKROE_PRESSURE3_REG_COEF_C21_LSB 0x1F
+#define MIKROE_PRESSURE3_REG_COEF_C30_MSB 0x20
+#define MIKROE_PRESSURE3_REG_COEF_C30_LSB 0x21
+#define MIKROE_PRESSURE3_REG_COEF_SRCE 0x28
+
+/** \} */
+
+/**
+ * \defgroup pressure_configuration Pressure Configuration
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_1_PER_SEC 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_2_PER_SEC 0x10
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_4_PER_SEC 0x20
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_8_PER_SEC 0x30
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_16_PER_SEC 0x40
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_32_PER_SEC 0x50
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_64_PER_SEC 0x60
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_128_PER_SEC 0x70
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_1_PER_SEC 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_2_PER_SEC 0x01
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_4_PER_SEC 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_8_PER_SEC 0x03
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_16_PER_SEC 0x04
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_32_PER_SEC 0x05
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_64_PER_SEC 0x06
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_128_PER_SEC 0x07
+
+/** \} */
+
+/**
+ * \defgroup Temperature_configuration Temperature Configuration
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_EXT_INTERNAL_SENSOR 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_EXT_EXTERNAL_SENSOR 0x80
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_1_PER_SEC 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_2_PER_SEC 0x10
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_4_PER_SEC 0x20
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_8_PER_SEC 0x30
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_16_PER_SEC 0x40
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_32_PER_SEC 0x50
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_64_PER_SEC 0x60
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_128_PER_SEC 0x70
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_1_PER_SEC 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_2_PER_SEC 0x01
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_4_PER_SEC 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_8_PER_SEC 0x03
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_16_PER_SEC 0x04
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_32_PER_SEC 0x05
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_64_PER_SEC 0x06
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_128_PER_SEC 0x07
+
+/** \} */
+
+/**
+ * \defgroup senor_operating_mode_and_status Sensor Operating Mode and Status
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_COEF_RDY_AVB 0x80
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_COEF_RDY_NO_AVB 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_SENSOR_RDY_CMP 0x40
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_SENSOR_RDY_NO_CMP 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_TMP_RDY 0x20
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_PRS_RDY 0x10
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_IDLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_PRS 0x01
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_TMP 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_CNT_PRS 0x05
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_CNT_TMP 0x06
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_CNT_PRS_TMP 0x07
+
+/** \} */
+
+/**
+ * \defgroup interrupt_and_fifo_configuration Interrupt and FIFO
+ * configuration
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_HL_LOW 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_HL_HIGH 0x80
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_FIFO_DISABLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_FIFO_ENABLE 0x40
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_TMP_DISABLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_TMP_ENABLE 0x20
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_PRS_DISABLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_PRS_ENABLE 0x10
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_T_SHIFT_NO_SHIFT 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_T_SHIFT_SHIFT 0x08
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_P_SHIFT_NO_SHIFT 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_P_SHIFT_SHIFT 0x04
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_FIFO_EN_DISABLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_FIFO_EN_ENABLE 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_SPI_MODE_DISABLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_SPI_MODE_ENABLE 0x01
+
+/** \} */
+
+/**
+ * \defgroup interrupt_status Interrupt Status
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_FIFO_FULL_NO_ACTIVE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_FIFO_FULL_ACTIVE 0x04
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_TMP_NO_ACTIVE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_TMP_ACTIVE 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_PRS_NO_ACTIVE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_PRS_ACTIVE 0x01
+
+/** \} */
+
+/**
+ * \defgroup fifo_status FIFO Status
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_FIFO_STS_FIFO_FULL_NO 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_FIFO_STS_FIFO_FULL_FULL 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_FIFO_STS_FIFO_EMPTY_NO 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_FIFO_STS_FIFO_EMPTY_EMPTY 0x01
+
+/** \} */
+
+/**
+ * \defgroup coefficients_source Coefficients Source
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_COEF_SRCE_INTERNAL_SENSOR 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_COEF_SRCE_EXTERNAL_SENSOR 0x80
+
+/** \} */
+
+/** \} */ // End group macro
+// --------------------------------------------------------------- PUBLIC TYPES
+
+/**
+ * \defgroup type Types
+ * \{
+ */
+
+/**
+ * @brief Communication type.
+ */
+typedef uint8_t mikroe_pressure3_select_t;
+
+/**
+ * @brief Coefficients structure.
+ */
+typedef struct
+{
+ int16_t coeff_c0;
+ int16_t coeff_c1;
+ int32_t coeff_c00;
+ int32_t coeff_c10;
+ int16_t coeff_c01;
+ int16_t coeff_c11;
+ int16_t coeff_c20;
+ int16_t coeff_c21;
+ int16_t coeff_c30;
+} mikroe_pressure3_coeff_t;
+
+/** \} */ // End types group
+// ----------------------------------------------- PUBLIC FUNCTION DECLARATIONS
+
+/**
+ * \defgroup public_function Public function
+ * \{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialization function.
+ *
+ * @param i2cspm_instance i2c instance.
+ *
+ * @description This function initializes all necessary pins and peripherals
+ * used for this click.
+ */
+sl_status_t mikroe_pressure3_init(sl_i2cspm_t *i2cspm_instance);
+
+/**
+ * @brief Generic write function.
+ *
+ * @param reg Register address.
+ * @param data_buf Output data buf
+ * @param len Number of the bytes to be read
+ *
+ * @description This function writes data to the desired register.
+ */
+sl_status_t mikroe_pressure3_generic_write(uint8_t reg,
+ uint8_t *data_buf,
+ uint8_t len);
+
+/**
+ * @brief Generic read function.
+ *
+ * @param reg Register address.
+ * @param data_buf Data buf to be written.
+ * @param len Number of the bytes in data buf.
+ *
+ * @description This function reads data from the desired register.
+ */
+sl_status_t mikroe_pressure3_generic_read(uint8_t reg,
+ uint8_t *data_buf,
+ uint8_t len);
+
+/**
+ * @brief Get temperature pressure.
+ *
+ * @param temperature pointer to float temperature value in degrees
+ * Celsius [ �C ].
+ * @param presure pointer to float presure value [ mbar ].
+ *
+ * @description This function reads data from the desired register.
+ */
+sl_status_t mikroe_pressure3_get_t_p_data(float *temperature, float *pressure);
+
+/**
+ * @brief Get coefficients.
+ *
+ * @param coeff_struct Structure.
+ *
+ * @description This function read the measurement data by read from the
+ * three target register address of DPS310 sensor on Pressure 3 click board.
+ */
+sl_status_t mikroe_pressure3_get_coefficients(
+ mikroe_pressure3_coeff_t *coeff_struct);
+
+/**
+ * @brief Read the value from the desired register.
+ *
+ * @param mbs_reg_addr register address.
+ *
+ * @description This function reads data from the desired register.
+ */
+int32_t mikroe_pressure3_get_measurement_data(uint8_t mbs_reg_addr);
+
+/**
+ * @brief Set the pressure configuration function.
+ *
+ * @param press_config pressConfig
+ * - [ bit7 ]
+ * - Reserved.
+ * - [ bit6 : bit4 ] Pressure measurement rate:
+ * - 000 : 1 measurements pr. sec.
+ * - 001 : 2 measurements pr. sec.
+ * - 010 : 4 measurements pr. sec.
+ * - 011 : 8 measurements pr. sec.
+ * - 100 : 16 measurements pr. sec.
+ * - 101 : 32 measurements pr. sec.
+ * - 110 : 64 measurements pr. sec.
+ * - 111 : 128 measurements pr. sec.
+ * - [ bit3 : bit0 ] Pressure oversampling rate:
+ * - 0000 : Single. (Low Precision)
+ * - 0001 : 2 times (Low Power).
+ * - 0010 : 4 times.
+ * - 0011 : 8 times.
+ * - 0100 : 16 times (Standard).
+ * - 0101 : 32 times.
+ * - 0110 : 64 times (High Precision).
+ * - 0111 : 128 times.
+ * - 1xxx : Reserved
+ *
+ * @description This function set the pressure configuration by write
+ * pressConfig data to the
+ * target _PRESSURE3_REG_PRS_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+sl_status_t mikroe_pressure3_set_pressure_configuration(uint8_t press_config);
+
+/**
+ * @brief Get the pressure configuration function.
+ *
+ * @description This function get the pressure configuration by read from the
+ * target _PRESSURE3_REG_PRS_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_pressure_configuration (void);
+
+/**
+ * @brief Set the temperature configuration function.
+ *
+ * @param temp_config tempConfig
+ * - [ bit7 ]
+ * - 0 : Internal sensor (in ASIC)
+ * - 1 : External sensor (in pressure sensor MEMS element)
+ * - [ bit6 : bit4 ] Temperature measurement rate:
+ * - 000 : 1 measurements pr. sec.
+ * - 001 : 2 measurements pr. sec.
+ * - 010 : 4 measurements pr. sec.
+ * - 011 : 8 measurements pr. sec.
+ * - 100 : 16 measurements pr. sec.
+ * - 101 : 32 measurements pr. sec.
+ * - 110 : 64 measurements pr. sec.
+ * - 111 : 128 measurements pr. sec.
+ * - [ bit3 : bit0 ] Temperature oversampling (precision):
+ * - 0000 : single. (Default) - Measurement time 3.6 ms.
+ * - 0001 : 2 times (Low Power).
+ * - 0010 : 4 times.
+ * - 0011 : 8 times.
+ * - 0100 : 16 times (Standard).
+ * - 0101 : 32 times.
+ * - 0110 : 64 times (High Precision).
+ * - 0111 : 128 times.
+ * - 1xxx : Reserved
+ *
+ * @description This function set the temperature configuration by write
+ * tempConfig data to the
+ * target _PRESSURE3_REG_TMP_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+sl_status_t mikroe_pressure3_set_temperature_configuration(uint8_t temp_config);
+
+/**
+ * @brief Get the temperature configuration function.
+ *
+ * @description This function get the temperature configuration by write
+ * tempConfig data to the
+ * target _PRESSURE3_REG_TMP_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_temperature_configuration(void);
+
+/**
+ * @brief Get the sensor operating mode function.
+ *
+ * @param operation_mode 8 bits array according to user configuration.
+ *
+ * @description This function set the sensor operating mode by write
+ * operationMode data to the
+ * target _PRESSURE3_REG_MEAS_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+sl_status_t mikroe_pressure3_set_operating_mode(uint8_t operation_mode);
+
+/**
+ * @brief Get the sensor operating mode function.
+ *
+ * @description This function set the sensor operating mode by write
+ * operationMode data to the
+ * target _PRESSURE3_REG_MEAS_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_operating_mode(void);
+
+/**
+ * @brief Set the configuration function.
+ *
+ * @param confg_data 8 bits array according to user configuration.
+ *
+ * @description This function set the configuration by write confgData data to
+ * the
+ * target _PRESSURE3_REG_CFG_REG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+sl_status_t mikroe_pressure3_set_configuration(uint8_t confg_data);
+
+/**
+ * @brief Get the configuration function.
+ *
+ * @description This function get the configuration read the byte of data from
+ * the
+ * target _PRESSURE3_REG_CFG_REG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_configuration(void);
+
+/**
+ * @brief Get the interrupt status function.
+ *
+ * @description This function get the interrupt status by read the byte of data
+ * from the
+ * target _PRESSURE3_REG_INT_STS register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_interrupt_status(void);
+
+/**
+ * @brief Get the FIFO Status function.
+ *
+ * @description This function get the interrupt The FIFO is empty by read the
+ * byte of data from the
+ * target _PRESSURE3_REG_FIFO_STS register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_fifo_status(void);
+
+/**
+ * @brief Soft reset function.
+ *
+ * @description This function set soft reset by write 0x09 to the
+ * target _PRESSURE3_REG_RESET register of DPS310 sensor on Pressure 3 click
+ * board..
+ */
+sl_status_t mikroe_pressure3_soft_reset(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _MIKROE_PRESSURE3_H_
+
+/** \} */ // End public_function group
+/// \} // End click Driver group
+
+/*! @} */
+// ------------------------------------------------------------------------- END
diff --git a/driver/public/mikroe/pressure3_dps310/inc/mikroe_dps310_spi.h b/driver/public/mikroe/pressure3_dps310/inc/mikroe_dps310_spi.h
new file mode 100644
index 00000000..e95c4678
--- /dev/null
+++ b/driver/public/mikroe/pressure3_dps310/inc/mikroe_dps310_spi.h
@@ -0,0 +1,498 @@
+/***************************************************************************//**
+ * @file mikroe_dps310_spi.h
+ * @brief SCL DPS310 Prototypes
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef MIKROE_PRESSURE3_H
+#define MIKROE_PRESSURE3_H
+
+#include "sl_status.h"
+#include "drv_digital_out.h"
+#include "drv_digital_in.h"
+#include "drv_spi_master.h"
+
+// -------------------------------------------------------------- PUBLIC MACROS
+
+/**
+ * \defgroup macros Macros
+ * \{
+ */
+
+/** \} */
+
+/**
+ * \defgroup configuration_register Configuration Registers
+ * \{
+ */
+#define MIKROE_PRESSURE3_I2C_ADDRESS 0x76
+#define MIKROE_PRESSURE3_REG_PSR_B2 0x00
+#define MIKROE_PRESSURE3_REG_PSR_B1 0x01
+#define MIKROE_PRESSURE3_REG_PSR_B0 0x02
+#define MIKROE_PRESSURE3_REG_TMP_B2 0x03
+#define MIKROE_PRESSURE3_REG_TMP_B1 0x04
+#define MIKROE_PRESSURE3_REG_TMP_B0 0x05
+#define MIKROE_PRESSURE3_REG_PRS_CFG 0x06
+#define MIKROE_PRESSURE3_REG_TMP_CFG 0x07
+#define MIKROE_PRESSURE3_REG_MEAS_CFG 0x08
+#define MIKROE_PRESSURE3_REG_CFG_REG 0x09
+#define MIKROE_PRESSURE3_REG_INT_STS 0x0A
+#define MIKROE_PRESSURE3_REG_FIFO_STS 0x0B
+#define MIKROE_PRESSURE3_REG_RESET 0x0C
+#define MIKROE_PRESSURE3_REG_PRODUCT_ID 0x0D
+#define MIKROE_PRESSURE3_REG_COEF_C0_MBS 0x10
+#define MIKROE_PRESSURE3_REG_COEF_C0_LBS_C1_MBS 0x11
+#define MIKROE_PRESSURE3_REG_COEF_C1_LBS 0x12
+#define MIKROE_PRESSURE3_REG_COEF_C00_MBS 0x13
+#define MIKROE_PRESSURE3_REG_COEF_C00_LSB 0x14
+#define MIKROE_PRESSURE3_REG_COEF_C00_XLSB_C10_MSB 0x15
+#define MIKROE_PRESSURE3_REG_COEF_C10_LSB 0x16
+#define MIKROE_PRESSURE3_REG_COEF_C10_XLSB 0x17
+#define MIKROE_PRESSURE3_REG_COEF_C01_MSB 0x18
+#define MIKROE_PRESSURE3_REG_COEF_C01_LSB 0x19
+#define MIKROE_PRESSURE3_REG_COEF_C11_MSB 0x1A
+#define MIKROE_PRESSURE3_REG_COEF_C11_LSB 0x1B
+#define MIKROE_PRESSURE3_REG_COEF_C20_MSB 0x1C
+#define MIKROE_PRESSURE3_REG_COEF_C20_LSB 0x1D
+#define MIKROE_PRESSURE3_REG_COEF_C21_MSB 0x1E
+#define MIKROE_PRESSURE3_REG_COEF_C21_LSB 0x1F
+#define MIKROE_PRESSURE3_REG_COEF_C30_MSB 0x20
+#define MIKROE_PRESSURE3_REG_COEF_C30_LSB 0x21
+#define MIKROE_PRESSURE3_REG_COEF_SRCE 0x28
+
+/** \} */
+
+/**
+ * \defgroup pressure_configuration Pressure Configuration
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_1_PER_SEC 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_2_PER_SEC 0x10
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_4_PER_SEC 0x20
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_8_PER_SEC 0x30
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_16_PER_SEC 0x40
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_32_PER_SEC 0x50
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_64_PER_SEC 0x60
+#define MIKROE_PRESSURE3_BIT_MASK_PM_RATE_128_PER_SEC 0x70
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_1_PER_SEC 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_2_PER_SEC 0x01
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_4_PER_SEC 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_8_PER_SEC 0x03
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_16_PER_SEC 0x04
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_32_PER_SEC 0x05
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_64_PER_SEC 0x06
+#define MIKROE_PRESSURE3_BIT_MASK_PM_PRC_128_PER_SEC 0x07
+
+/** \} */
+
+/**
+ * \defgroup Temperature_configuration Temperature Configuration
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_EXT_INTERNAL_SENSOR 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_EXT_EXTERNAL_SENSOR 0x80
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_1_PER_SEC 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_2_PER_SEC 0x10
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_4_PER_SEC 0x20
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_8_PER_SEC 0x30
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_16_PER_SEC 0x40
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_32_PER_SEC 0x50
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_64_PER_SEC 0x60
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_RATE_128_PER_SEC 0x70
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_1_PER_SEC 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_2_PER_SEC 0x01
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_4_PER_SEC 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_8_PER_SEC 0x03
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_16_PER_SEC 0x04
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_32_PER_SEC 0x05
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_64_PER_SEC 0x06
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_PRC_128_PER_SEC 0x07
+
+/** \} */
+
+/**
+ * \defgroup senor_operating_mode_and_status Sensor Operating Mode and Status
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_COEF_RDY_AVB 0x80
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_COEF_RDY_NO_AVB 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_SENSOR_RDY_CMP 0x40
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_SENSOR_RDY_NO_CMP 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_TMP_RDY 0x20
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_PRS_RDY 0x10
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_IDLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_PRS 0x01
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_TMP 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_CNT_PRS 0x05
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_CNT_TMP 0x06
+#define MIKROE_PRESSURE3_BIT_MASK_MEAS_CFG_MEAS_CTRL_CNT_PRS_TMP 0x07
+
+/** \} */
+
+/**
+ * \defgroup interrupt_and_fifo_configuration Interrupt and FIFO
+ * configuration
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_HL_LOW 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_HL_HIGH 0x80
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_FIFO_DISABLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_FIFO_ENABLE 0x40
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_TMP_DISABLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_TMP_ENABLE 0x20
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_PRS_DISABLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_INT_PRS_ENABLE 0x10
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_T_SHIFT_NO_SHIFT 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_T_SHIFT_SHIFT 0x08
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_P_SHIFT_NO_SHIFT 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_P_SHIFT_SHIFT 0x04
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_FIFO_EN_DISABLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_FIFO_EN_ENABLE 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_SPI_MODE_DISABLE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_CFG_REG_SPI_MODE_ENABLE 0x01
+
+/** \} */
+
+/**
+ * \defgroup interrupt_status Interrupt Status
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_FIFO_FULL_NO_ACTIVE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_FIFO_FULL_ACTIVE 0x04
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_TMP_NO_ACTIVE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_TMP_ACTIVE 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_PRS_NO_ACTIVE 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_INT_STS_INT_PRS_ACTIVE 0x01
+
+/** \} */
+
+/**
+ * \defgroup fifo_status FIFO Status
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_FIFO_STS_FIFO_FULL_NO 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_FIFO_STS_FIFO_FULL_FULL 0x02
+#define MIKROE_PRESSURE3_BIT_MASK_FIFO_STS_FIFO_EMPTY_NO 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_FIFO_STS_FIFO_EMPTY_EMPTY 0x01
+
+/** \} */
+
+/**
+ * \defgroup coefficients_source Coefficients Source
+ * \{
+ */
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_COEF_SRCE_INTERNAL_SENSOR 0x00
+#define MIKROE_PRESSURE3_BIT_MASK_TMP_COEF_SRCE_EXTERNAL_SENSOR 0x80
+
+/** \} */
+
+/** \} */ // End group macro
+// --------------------------------------------------------------- PUBLIC TYPES
+
+/**
+ * \defgroup type Types
+ * \{
+ */
+
+/**
+ * @brief Communication type.
+ */
+typedef uint8_t mikroe_pressure3_select_t;
+
+/**
+ * @brief Coefficients structure.
+ */
+typedef struct
+{
+ int16_t coeff_c0;
+ int16_t coeff_c1;
+ int32_t coeff_c00;
+ int32_t coeff_c10;
+ int16_t coeff_c01;
+ int16_t coeff_c11;
+ int16_t coeff_c20;
+ int16_t coeff_c21;
+ int16_t coeff_c30;
+} mikroe_pressure3_coeff_t;
+
+/** \} */ // End types group
+// ----------------------------------------------- PUBLIC FUNCTION DECLARATIONS
+
+/**
+ * \defgroup public_function Public function
+ * \{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Initialization function.
+ *
+ * @param spidrv_inst spi instance.
+ *
+ * @description This function initializes all necessary pins and peripherals
+ * used for this click.
+ */
+sl_status_t mikroe_pressure3_init(SPIDRV_Handle_t spidrv_inst);
+
+/**
+ * @brief Generic write function.
+ *
+ * @param reg Register address.
+ * @param data_buf Output data buf
+ * @param len Number of the bytes to be read
+ *
+ * @description This function writes data to the desired register.
+ */
+sl_status_t mikroe_pressure3_generic_write(uint8_t reg,
+ uint8_t *data_buf,
+ uint8_t len);
+
+/**
+ * @brief Generic read function.
+ *
+ * @param reg Register address.
+ * @param data_buf Data buf to be written.
+ * @param len Number of the bytes in data buf.
+ *
+ * @description This function reads data from the desired register.
+ */
+sl_status_t mikroe_pressure3_generic_read(uint8_t reg,
+ uint8_t *data_buf,
+ uint8_t len);
+
+/**
+ * @brief Get temperature pressure.
+ *
+ * @param temperature pointer to float temperature value in degrees
+ * Celsius [ �C ].
+ * @param presure pointer to float presure value [ mbar ].
+ *
+ * @description This function reads data from the desired register.
+ */
+sl_status_t mikroe_pressure3_get_t_p_data(float *temperature, float *pressure);
+
+/**
+ * @brief Get coefficients.
+ *
+ * @param coeff_struct Structure.
+ *
+ * @description This function read the measurement data by read from the
+ * three target register address of DPS310 sensor on Pressure 3 click board.
+ */
+sl_status_t mikroe_pressure3_get_coefficients(
+ mikroe_pressure3_coeff_t *coeff_struct);
+
+/**
+ * @brief Read the value from the desired register.
+ *
+ * @param mbs_reg_addr register address.
+ *
+ * @description This function reads data from the desired register.
+ */
+int32_t mikroe_pressure3_get_measurement_data(uint8_t mbs_reg_addr);
+
+/**
+ * @brief Set the pressure configuration function.
+ *
+ * @param press_config pressConfig
+ * - [ bit7 ]
+ * - Reserved.
+ * - [ bit6 : bit4 ] Pressure measurement rate:
+ * - 000 : 1 measurements pr. sec.
+ * - 001 : 2 measurements pr. sec.
+ * - 010 : 4 measurements pr. sec.
+ * - 011 : 8 measurements pr. sec.
+ * - 100 : 16 measurements pr. sec.
+ * - 101 : 32 measurements pr. sec.
+ * - 110 : 64 measurements pr. sec.
+ * - 111 : 128 measurements pr. sec.
+ * - [ bit3 : bit0 ] Pressure oversampling rate:
+ * - 0000 : Single. (Low Precision)
+ * - 0001 : 2 times (Low Power).
+ * - 0010 : 4 times.
+ * - 0011 : 8 times.
+ * - 0100 : 16 times (Standard).
+ * - 0101 : 32 times.
+ * - 0110 : 64 times (High Precision).
+ * - 0111 : 128 times.
+ * - 1xxx : Reserved
+ *
+ * @description This function set the pressure configuration by write
+ * pressConfig data to the
+ * target _PRESSURE3_REG_PRS_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+sl_status_t mikroe_pressure3_set_pressure_configuration(uint8_t press_config);
+
+/**
+ * @brief Get the pressure configuration function.
+ *
+ * @description This function get the pressure configuration by read from the
+ * target _PRESSURE3_REG_PRS_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_pressure_configuration (void);
+
+/**
+ * @brief Set the temperature configuration function.
+ *
+ * @param temp_config tempConfig
+ * - [ bit7 ]
+ * - 0 : Internal sensor (in ASIC)
+ * - 1 : External sensor (in pressure sensor MEMS element)
+ * - [ bit6 : bit4 ] Temperature measurement rate:
+ * - 000 : 1 measurements pr. sec.
+ * - 001 : 2 measurements pr. sec.
+ * - 010 : 4 measurements pr. sec.
+ * - 011 : 8 measurements pr. sec.
+ * - 100 : 16 measurements pr. sec.
+ * - 101 : 32 measurements pr. sec.
+ * - 110 : 64 measurements pr. sec.
+ * - 111 : 128 measurements pr. sec.
+ * - [ bit3 : bit0 ] Temperature oversampling (precision):
+ * - 0000 : single. (Default) - Measurement time 3.6 ms.
+ * - 0001 : 2 times (Low Power).
+ * - 0010 : 4 times.
+ * - 0011 : 8 times.
+ * - 0100 : 16 times (Standard).
+ * - 0101 : 32 times.
+ * - 0110 : 64 times (High Precision).
+ * - 0111 : 128 times.
+ * - 1xxx : Reserved
+ *
+ * @description This function set the temperature configuration by write
+ * tempConfig data to the
+ * target _PRESSURE3_REG_TMP_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+sl_status_t mikroe_pressure3_set_temperature_configuration(uint8_t temp_config);
+
+/**
+ * @brief Get the temperature configuration function.
+ *
+ * @description This function get the temperature configuration by write
+ * tempConfig data to the
+ * target _PRESSURE3_REG_TMP_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_temperature_configuration(void);
+
+/**
+ * @brief Get the sensor operating mode function.
+ *
+ * @param operation_mode 8 bits array according to user configuration.
+ *
+ * @description This function set the sensor operating mode by write
+ * operationMode data to the
+ * target _PRESSURE3_REG_MEAS_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+sl_status_t mikroe_pressure3_set_operating_mode(uint8_t operation_mode);
+
+/**
+ * @brief Get the sensor operating mode function.
+ *
+ * @description This function set the sensor operating mode by write
+ * operationMode data to the
+ * target _PRESSURE3_REG_MEAS_CFG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_operating_mode(void);
+
+/**
+ * @brief Set the configuration function.
+ *
+ * @param confg_data 8 bits array according to user configuration.
+ *
+ * @description This function set the configuration by write confgData data to
+ * the
+ * target _PRESSURE3_REG_CFG_REG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+sl_status_t mikroe_pressure3_set_configuration(uint8_t confg_data);
+
+/**
+ * @brief Get the configuration function.
+ *
+ * @description This function get the configuration read the byte of data from
+ * the
+ * target _PRESSURE3_REG_CFG_REG register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_configuration(void);
+
+/**
+ * @brief Get the interrupt status function.
+ *
+ * @description This function get the interrupt status by read the byte of data
+ * from the
+ * target _PRESSURE3_REG_INT_STS register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_interrupt_status(void);
+
+/**
+ * @brief Get the FIFO Status function.
+ *
+ * @description This function get the interrupt The FIFO is empty by read the
+ * byte of data from the
+ * target _PRESSURE3_REG_FIFO_STS register of DPS310 sensor on Pressure 3 click
+ * board.
+ */
+uint8_t mikroe_pressure3_get_fifo_status(void);
+
+/**
+ * @brief Soft reset function.
+ *
+ * @description This function set soft reset by write 0x09 to the
+ * target _PRESSURE3_REG_RESET register of DPS310 sensor on Pressure 3 click
+ * board..
+ */
+sl_status_t mikroe_pressure3_soft_reset(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _MIKROE_PRESSURE3_H_
+
+/** \} */ // End public_function group
+/// \} // End click Driver group
+
+/*! @} */
+// ------------------------------------------------------------------------- END
diff --git a/driver/public/mikroe/pressure3_dps310/src/mikroe_dps310_i2c.c b/driver/public/mikroe/pressure3_dps310/src/mikroe_dps310_i2c.c
new file mode 100644
index 00000000..daf5107b
--- /dev/null
+++ b/driver/public/mikroe/pressure3_dps310/src/mikroe_dps310_i2c.c
@@ -0,0 +1,188 @@
+/***************************************************************************//**
+ * @file mikroe_dps310_i2c.c
+ * @brief SCL DPS310 source file
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#include "mikroe_dps310_i2c.h"
+#include "pressure3.h"
+#include "sl_status.h"
+
+/********************************************************************************
+ * static variables
+ *******************************************************************************/
+
+static pressure3_coeff_t coeff_struct;
+static pressure3_t ctx;
+
+/********************************************************************************
+ * public function
+ *******************************************************************************/
+sl_status_t mikroe_pressure3_init(sl_i2cspm_t *i2cspm_instance)
+{
+ pressure3_cfg_t cfg;
+
+ if (i2cspm_instance == NULL) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ // Call basic setup functions
+ pressure3_cfg_setup(&cfg);
+ // Configure default i2csmp instance
+ ctx.i2c.handle = i2cspm_instance;
+ if (PRESSURE3_OK != pressure3_init(&ctx, &cfg)) {
+ return SL_STATUS_FAIL;
+ } else {
+ pressure3_default_cfg(&ctx);
+ return SL_STATUS_OK;
+ }
+}
+
+sl_status_t mikroe_pressure3_generic_write(uint8_t reg,
+ uint8_t *data_buf,
+ uint8_t len)
+{
+ if ((data_buf == NULL) || (len == 0)) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ pressure3_generic_write(&ctx, reg, data_buf, len);
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_pressure3_generic_read(uint8_t reg,
+ uint8_t *data_buf,
+ uint8_t len)
+{
+ if ((data_buf == NULL) || (len == 0)) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ pressure3_generic_read(&ctx, reg, data_buf, len);
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_pressure3_get_t_p_data(float *temperature,
+ float *pressure)
+{
+ if ((temperature == NULL) || (pressure == NULL)) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ pressure3_get_t_p_data(&ctx,
+ temperature,
+ pressure,
+ &coeff_struct);
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_pressure3_get_coefficients(
+ mikroe_pressure3_coeff_t *coeff_struct)
+{
+ if (coeff_struct == NULL) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ pressure3_get_coefficients(&ctx, (pressure3_coeff_t *)coeff_struct);
+ return SL_STATUS_OK;
+}
+
+int32_t mikroe_pressure3_get_measurement_data(uint8_t mbs_reg_addr)
+{
+ return pressure3_get_measurement_data(&ctx, mbs_reg_addr);
+}
+
+sl_status_t mikroe_pressure3_set_pressure_configuration(uint8_t press_config)
+{
+ pressure3_set_pressure_configuration(&ctx, press_config);
+ return SL_STATUS_OK;
+}
+
+uint8_t mikroe_pressure3_get_pressure_configuration(void)
+{
+ return pressure3_get_pressure_configuration(&ctx);
+}
+
+sl_status_t mikroe_pressure3_set_temperature_configuration(uint8_t temp_config)
+{
+ pressure3_set_temperature_configuration(&ctx, temp_config);
+ return SL_STATUS_OK;
+}
+
+uint8_t mikroe_pressure3_get_temperature_configuration(void)
+{
+ return pressure3_get_temperature_configuration(&ctx);
+}
+
+sl_status_t mikroe_pressure3_set_operating_mode(uint8_t operation_mode)
+{
+ pressure3_set_operating_mode(&ctx, operation_mode);
+ return SL_STATUS_OK;
+}
+
+uint8_t mikroe_pressure3_get_operating_mode(void)
+{
+ return pressure3_get_operating_mode(&ctx);
+}
+
+sl_status_t mikroe_pressure3_set_configuration(uint8_t confg_data)
+{
+ pressure3_set_configuration(&ctx, confg_data);
+ return SL_STATUS_OK;
+}
+
+uint8_t mikroe_pressure3_get_configuration(void)
+{
+ return pressure3_get_configuration(&ctx);
+}
+
+uint8_t mikroe_pressure3_get_interrupt_status(void)
+{
+ return pressure3_get_interrupt_status(&ctx);
+}
+
+uint8_t mikroe_pressure3_get_fifo_status(void)
+{
+ return pressure3_get_fifo_status(&ctx);
+}
+
+sl_status_t mikroe_pressure3_soft_reset(void)
+{
+ pressure3_soft_reset(&ctx);
+ return SL_STATUS_OK;
+}
+
+// ------------------------------------------------------------------------- END
diff --git a/driver/public/mikroe/pressure3_dps310/src/mikroe_dps310_spi.c b/driver/public/mikroe/pressure3_dps310/src/mikroe_dps310_spi.c
new file mode 100644
index 00000000..ba0b0fd1
--- /dev/null
+++ b/driver/public/mikroe/pressure3_dps310/src/mikroe_dps310_spi.c
@@ -0,0 +1,190 @@
+/***************************************************************************//**
+ * @file mikroe_dps310_spi.h
+ * @brief SCL DPS310 source file
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#include "mikroe_dps310_spi.h"
+#include "pressure3.h"
+#include "sl_status.h"
+
+/********************************************************************************
+ * static variables
+ *******************************************************************************/
+
+static pressure3_coeff_t coeff_struct;
+static pressure3_t ctx;
+
+/********************************************************************************
+ * public function
+ *******************************************************************************/
+sl_status_t mikroe_pressure3_init(SPIDRV_Handle_t spidrv_inst)
+{
+ pressure3_cfg_t cfg;
+
+ if (spidrv_inst == NULL) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ // Call basic setup functions
+ pressure3_cfg_setup(&cfg);
+ cfg.cs = hal_gpio_pin_name(spidrv_inst->portCs, spidrv_inst->pinCs);
+ cfg.sel = PRESSURE3_MASTER_SPI;
+ // Configure default i2csmp instance
+ ctx.spi.handle = spidrv_inst;
+ if (PRESSURE3_OK != pressure3_init(&ctx, &cfg)) {
+ return SL_STATUS_FAIL;
+ } else {
+ pressure3_default_cfg(&ctx);
+ return SL_STATUS_OK;
+ }
+}
+
+sl_status_t mikroe_pressure3_generic_write(uint8_t reg,
+ uint8_t *data_buf,
+ uint8_t len)
+{
+ if ((data_buf == NULL) || (len == 0)) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ pressure3_generic_write(&ctx, reg, data_buf, len);
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_pressure3_generic_read(uint8_t reg,
+ uint8_t *data_buf,
+ uint8_t len)
+{
+ if ((data_buf == NULL) || (len == 0)) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ pressure3_generic_read(&ctx, reg, data_buf, len);
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_pressure3_get_t_p_data(float *temperature,
+ float *pressure)
+{
+ if ((temperature == NULL) || (pressure == NULL)) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ pressure3_get_t_p_data(&ctx,
+ temperature,
+ pressure,
+ &coeff_struct);
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_pressure3_get_coefficients(
+ mikroe_pressure3_coeff_t *coeff_struct)
+{
+ if (coeff_struct == NULL) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ pressure3_get_coefficients(&ctx, (pressure3_coeff_t *)coeff_struct);
+ return SL_STATUS_OK;
+}
+
+int32_t mikroe_pressure3_get_measurement_data(uint8_t mbs_reg_addr)
+{
+ return pressure3_get_measurement_data(&ctx, mbs_reg_addr);
+}
+
+sl_status_t mikroe_pressure3_set_pressure_configuration(uint8_t press_config)
+{
+ pressure3_set_pressure_configuration(&ctx, press_config);
+ return SL_STATUS_OK;
+}
+
+uint8_t mikroe_pressure3_get_pressure_configuration(void)
+{
+ return pressure3_get_pressure_configuration(&ctx);
+}
+
+sl_status_t mikroe_pressure3_set_temperature_configuration(uint8_t temp_config)
+{
+ pressure3_set_temperature_configuration(&ctx, temp_config);
+ return SL_STATUS_OK;
+}
+
+uint8_t mikroe_pressure3_get_temperature_configuration(void)
+{
+ return pressure3_get_temperature_configuration(&ctx);
+}
+
+sl_status_t mikroe_pressure3_set_operating_mode(uint8_t operation_mode)
+{
+ pressure3_set_operating_mode(&ctx, operation_mode);
+ return SL_STATUS_OK;
+}
+
+uint8_t mikroe_pressure3_get_operating_mode(void)
+{
+ return pressure3_get_operating_mode(&ctx);
+}
+
+sl_status_t mikroe_pressure3_set_configuration(uint8_t confg_data)
+{
+ pressure3_set_configuration(&ctx, confg_data);
+ return SL_STATUS_OK;
+}
+
+uint8_t mikroe_pressure3_get_configuration(void)
+{
+ return pressure3_get_configuration(&ctx);
+}
+
+uint8_t mikroe_pressure3_get_interrupt_status(void)
+{
+ return pressure3_get_interrupt_status(&ctx);
+}
+
+uint8_t mikroe_pressure3_get_fifo_status(void)
+{
+ return pressure3_get_fifo_status(&ctx);
+}
+
+sl_status_t mikroe_pressure3_soft_reset(void)
+{
+ pressure3_soft_reset(&ctx);
+ return SL_STATUS_OK;
+}
+
+// ------------------------------------------------------------------------- END
diff --git a/driver/public/mikroe/pwm_driver_si8711cc/inc/mikroe_si8711cc.h b/driver/public/mikroe/pwm_driver_si8711cc/inc/mikroe_si8711cc.h
new file mode 100644
index 00000000..c0a25457
--- /dev/null
+++ b/driver/public/mikroe/pwm_driver_si8711cc/inc/mikroe_si8711cc.h
@@ -0,0 +1,125 @@
+/***************************************************************************//**
+ * @file mikroe_si8711cc.h
+ * @brief mikroe_si8711cc.h
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef MIKROE_SI8711CC_H_
+#define MIKROE_SI8711CC_H_
+#include "sl_status.h"
+#include "sl_pwm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @brief
+ * Initialization function.
+ *
+ * @param[in] pwm_instance
+ * PWM instance
+ *
+ * @return
+ * SL_STATUS_OK Successful initialization.
+ * SL_STATUS_FAIL Initialization failed.
+ ******************************************************************************/
+sl_status_t mikroe_si8711cc_init(sl_pwm_instance_t *pwm_instance);
+
+/***************************************************************************//**
+ * @brief
+ * This function sets the PWM instance used by platform functions.
+ *
+ * @param[in] pwm_instance
+ * PWM instance, default: sl_pwm_mikroe
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_INVALID_PARAMETER if pwm_instance is null.
+ ******************************************************************************/
+sl_status_t mikroe_si8711cc_set_pwm_instance(
+ sl_pwm_instance_t *pwm_instance);
+
+/***************************************************************************//**
+ * @brief
+ * This function sets duty cycle for PWM Driver
+ *
+ * @param[in] duty_cycle
+ * duty cycle value
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_FAIL
+ ******************************************************************************/
+sl_status_t mikroe_si8711cc_set_duty_cycle (float duty_cycle);
+
+/***************************************************************************//**
+ * @brief
+ * This function sets frequency for PWM Driver
+ *
+ * @param[in] frequency
+ * frequency value
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_FAIL
+ ******************************************************************************/
+sl_status_t mikroe_si8711cc_set_frequency (uint16_t frequency);
+
+/***************************************************************************//**
+ * @brief
+ * This function is used to stop pwm for PWM Driver
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_FAIL
+ ******************************************************************************/
+sl_status_t mikroe_si8711cc_pwm_stop (void);
+
+/***************************************************************************//**
+ * @brief
+ * This function is used to start pwm for PWM Driver
+ *
+ * @return
+ * SL_STATUS_OK if there are no errors.
+ * SL_STATUS_FAIL
+ ******************************************************************************/
+sl_status_t mikroe_si8711cc_pwm_start (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_SI8711CC_H_ */
diff --git a/driver/public/mikroe/pwm_driver_si8711cc/src/mikroe_si8711cc.c b/driver/public/mikroe/pwm_driver_si8711cc/src/mikroe_si8711cc.c
new file mode 100644
index 00000000..7ac9bb18
--- /dev/null
+++ b/driver/public/mikroe/pwm_driver_si8711cc/src/mikroe_si8711cc.c
@@ -0,0 +1,102 @@
+/***************************************************************************//**
+ * @file mikroe_si8711cc.c
+ * @brief mikroe_si8711cc.c
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#include "mikroe_si8711cc.h"
+#include "stddef.h"
+#include "third_party_hw_drivers_helpers.h"
+#include "pwmdriver.h"
+
+static pwmdriver_t pwm_driver;
+static pwmdriver_cfg_t pwm_driver_cfg;
+
+sl_status_t mikroe_si8711cc_init(sl_pwm_instance_t *pwm_instance)
+{
+ if (NULL == pwm_instance) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ THIRD_PARTY_HW_DRV_RETCODE_INIT();
+
+ // Configure default i2csmp instance
+ pwm_driver.pwm.handle = pwm_instance;
+
+ // Call basic setup functions
+ pwmdriver_cfg_setup(&pwm_driver_cfg);
+
+ THIRD_PARTY_HW_DRV_RETCODE_TEST(pwmdriver_init(&pwm_driver,
+ &pwm_driver_cfg));
+
+ return THIRD_PARTY_HW_DRV_RETCODE_VALUE;
+}
+
+sl_status_t mikroe_si8711cc_set_pwm_instance(sl_pwm_instance_t *pwm_instance)
+{
+ if (NULL == pwm_instance) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ pwm_driver.pwm.handle = pwm_instance;
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_si8711cc_set_duty_cycle(float duty_cycle)
+{
+ pwmdriver_set_duty_cycle(&pwm_driver, duty_cycle);
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_si8711cc_set_frequency(uint16_t frequency)
+{
+ return pwm_set_freq(&pwm_driver.pwm, frequency);
+}
+
+sl_status_t mikroe_si8711cc_pwm_stop(void)
+{
+ pwmdriver_pwm_stop(&pwm_driver);
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_si8711cc_pwm_start(void)
+{
+ pwmdriver_pwm_start(&pwm_driver);
+
+ return SL_STATUS_OK;
+}
diff --git a/driver/public/mikroe/rf_meter_ad8318/inc/mikroe_ad8318.h b/driver/public/mikroe/rf_meter_ad8318/inc/mikroe_ad8318.h
new file mode 100644
index 00000000..6b4fc179
--- /dev/null
+++ b/driver/public/mikroe/rf_meter_ad8318/inc/mikroe_ad8318.h
@@ -0,0 +1,143 @@
+/***************************************************************************//**
+ * @file mirkroe_ad8318.h
+ * @brief SCL ad8318 Prototypes
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef MIKROE_AD8318_H_
+#define MIKROE_AD8318_H_
+
+#include "sl_status.h"
+#include "spidrv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup calc_const Calculation constants
+ * \{
+ */
+#define MIKROE_AD8318_FILTER_USEFULL_DATA 0x1FFE
+#define MIKROE_AD8318_ADC_RESOLUTION 4096
+#define MIKROE_AD8318_DATA_SAMPLE_NUM 10
+#define MIKROE_AD8318_DEF_VREF 2.5
+#define MIKROE_AD8318_DEF_SLOPE -0.025
+#define MIKROE_AD8318_DEF_INTERCEPT 20.0
+#define MIKROE_AD8318_DEF_LIMIT_HIGH 2.0
+#define MIKROE_AD8318_DEF_LIMIT_LOW 0.5
+
+/** \} */
+
+/**
+ * @brief Config Object Initialization function.
+ *
+ * @description This function initializes click configuration structure to init
+ * state.
+ * @note All used pins will be set to unconnected state.
+ */
+void mikroe_ad8318_cfg_setup(void);
+
+/**
+ * @brief Initialization function.
+ * @param spi_instance SPI handle instance.
+ *
+ * @description This function initializes all necessary pins and peripherals
+ * used for this click.
+ */
+sl_status_t mikroe_ad8318_set_spi_instance(SPIDRV_Handle_t spi_instance);
+
+/**
+ * @brief Initialization function.
+ * @param spi_instance SPI handle instance.
+ *
+ * @description This function initializes all necessary pins and peripherals
+ * used for this click.
+ */
+sl_status_t mikroe_ad8318_init(SPIDRV_Handle_t spi_instance);
+
+/**
+ * @brief Data read function
+ *
+ * @param read_data Data readed.
+ *
+ * @returns status of function.
+ *
+ * Function is used to read data from output register.
+ **/
+sl_status_t mikroe_ad8318_read_data(uint16_t *read_data);
+
+/**
+ * @brief Get raw data function
+ *
+ * @param raw_data Raw data.
+ *
+ * @returns status of function.
+ *
+ * Function is used to read raw data value from output register.
+ **/
+sl_status_t mikroe_ad8318_get_raw_data(uint16_t *raw_data);
+
+/**
+ * @brief Get voltage function
+ *
+ * @param voltage Voltage.
+ *
+ * @returns status of function.
+ *
+ * Function is used to read raw voltage value from output register.
+ **/
+sl_status_t mikroe_ad8318_get_voltage(float *voltage);
+
+/**
+ * @brief Get signal strenght function
+ *
+ * @param slope float value that represents slope
+ * @param intercept float value that represents intercept
+ * @param signal_strength Signal strenght.
+ * @returns status of function.
+ *
+ * Function is used to calculate radio frequency signal strenght in a vicinity.
+ **/
+sl_status_t mikroe_ad8318_get_signal_strength(float slope,
+ float intercept,
+ float *signal_strength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MIKROE_AD8318_H_ */
diff --git a/driver/public/mikroe/rf_meter_ad8318/src/mikroe_ad8318.c b/driver/public/mikroe/rf_meter_ad8318/src/mikroe_ad8318.c
new file mode 100644
index 00000000..957df7ef
--- /dev/null
+++ b/driver/public/mikroe/rf_meter_ad8318/src/mikroe_ad8318.c
@@ -0,0 +1,126 @@
+/***************************************************************************//**
+ * @file mirkroe_ad8318c
+ * @brief SCL ad8318 Source code file.
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#include "mikroe_ad8318.h"
+#include "third_party_hw_drivers_helpers.h"
+#include "rfmeter.h"
+
+static rfmeter_t rf_meter;
+static rfmeter_cfg_t rf_meter_cfg;
+
+void mikroe_ad8318_cfg_setup(void)
+{
+ rfmeter_cfg_setup(&rf_meter_cfg);
+}
+
+sl_status_t mikroe_ad8318_set_spi_instance(SPIDRV_Handle_t spi_instance)
+{
+ if (NULL == spi_instance) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ rf_meter.spi.handle = spi_instance;
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_ad8318_init(SPIDRV_Handle_t spi_instance)
+{
+ if (NULL == spi_instance) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ THIRD_PARTY_HW_DRV_RETCODE_INIT();
+
+ rfmeter_cfg_setup(&rf_meter_cfg);
+
+ rf_meter.spi.handle = spi_instance;
+ rf_meter_cfg.cs = hal_gpio_pin_name(spi_instance->portCs,
+ spi_instance->pinCs);
+
+ THIRD_PARTY_HW_DRV_RETCODE_TEST(rfmeter_init(&rf_meter, &rf_meter_cfg));
+
+ return THIRD_PARTY_HW_DRV_RETCODE_VALUE;
+}
+
+sl_status_t mikroe_ad8318_read_data(uint16_t *read_data)
+{
+ if (NULL == read_data) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ *read_data = rfmeter_read_data(&rf_meter);
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_ad8318_get_raw_data(uint16_t *raw_data)
+{
+ if (NULL == raw_data) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ *raw_data = rfmeter_get_raw_data(&rf_meter);
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_ad8318_get_voltage(float *voltage)
+{
+ if (NULL == voltage) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ *voltage = rfmeter_get_voltage(&rf_meter);
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t mikroe_ad8318_get_signal_strength(float slope,
+ float intercept,
+ float *signal_strength)
+{
+ if (NULL == signal_strength) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ *signal_strength = rfmeter_get_signal_strenght(&rf_meter, slope, intercept);
+
+ return SL_STATUS_OK;
+}
diff --git a/driver/public/silabs/fatfs_sdc_spi_platform/inc/sl_sdc_platform_spi.h b/driver/public/silabs/fatfs_sdc_spi_platform/inc/sl_sdc_platform_spi.h
new file mode 100644
index 00000000..df6b602a
--- /dev/null
+++ b/driver/public/silabs/fatfs_sdc_spi_platform/inc/sl_sdc_platform_spi.h
@@ -0,0 +1,98 @@
+/***************************************************************************//**
+ * @file sl_sdc_platform_spi.h
+ * @brief Storage Device Controls SD Card platform include header
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ ********************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#ifndef SL_SDC_PLATFORM_SPI_H
+#define SL_SDC_PLATFORM_SPI_H
+
+#include "sl_status.h"
+#include "spidrv.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @brief
+ * Exchange a byte.
+ *
+ * @param[out] data
+ * Pointer to the data buffer to be exchange
+ *
+ * @return
+ * @ref SL_STATUS_OK on success or @ref SL_STATUS_TRANSMIT on failure
+ ******************************************************************************/
+sl_status_t sdc_xchg_spi(SPIDRV_Handle_t spi_handle, uint8_t tx, uint8_t *rx);
+
+/***************************************************************************//**
+ * @brief
+ * Multi-byte SPI transaction (transmit).
+ *
+ * @param[in] buff
+ * Pointer to the data buffer to be sent
+ *
+ * @param[in] cnt
+ * Number of bytes to send
+ *
+ * @return
+ * @ref SL_STATUS_OK on success or @ref SL_STATUS_TRANSMIT on failure
+ ******************************************************************************/
+sl_status_t sdc_xmit_spi_multi(SPIDRV_Handle_t spi_handle,
+ const uint8_t *buff,
+ uint16_t cnt);
+
+/***************************************************************************//**
+ * @brief
+ * Multi-byte SPI transaction (receive).
+ *
+ * @param[out] buff
+ * Pointer to the data Buffer to store received data
+ *
+ * @param[in] cnt
+ * Number of bytes to receive
+ *
+ * @return
+ * @ref SL_STATUS_OK on success or @ref SL_STATUS_TRANSMIT on failure
+ ******************************************************************************/
+sl_status_t sdc_rcvr_spi_multi(SPIDRV_Handle_t spi_handle,
+ uint8_t *buff,
+ uint16_t cnt);
+
+sl_status_t sdc_platform_set_bit_rate(SPIDRV_Handle_t spi_handle,
+ uint32_t bit_rate);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SL_SDC_PLATFORM_SPI_H
diff --git a/driver/public/silabs/fatfs_sdc_spi_platform/src/sl_sdc_platform_spi.c b/driver/public/silabs/fatfs_sdc_spi_platform/src/sl_sdc_platform_spi.c
new file mode 100644
index 00000000..0c1ca37b
--- /dev/null
+++ b/driver/public/silabs/fatfs_sdc_spi_platform/src/sl_sdc_platform_spi.c
@@ -0,0 +1,113 @@
+/***************************************************************************//**
+ * @file sl_sdc_platform_spi.c
+ * @brief Storage Device Controls SD Card platform
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ ********************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+#include "sl_sdc_platform_spi.h"
+
+/***************************************************************************//**
+ * Exchange a byte.
+ ******************************************************************************/
+sl_status_t sdc_xchg_spi(SPIDRV_Handle_t spi_handle, uint8_t tx, uint8_t *rx)
+{
+ sl_status_t retval;
+
+ if (!spi_handle) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+ retval = SPIDRV_MTransferB(spi_handle, &tx, rx, 1);
+ if (retval != ECODE_EMDRV_SPIDRV_OK) {
+ *rx = 0;
+ return SL_STATUS_TRANSMIT;
+ }
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Multi-byte SPI transaction (transmit).
+ ******************************************************************************/
+sl_status_t sdc_xmit_spi_multi(SPIDRV_Handle_t spi_handle,
+ const uint8_t *buff,
+ uint16_t cnt)
+{
+ sl_status_t retval;
+
+ if (!spi_handle) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+ retval = SPIDRV_MTransmitB(spi_handle, buff, cnt);
+ if (retval != ECODE_EMDRV_SPIDRV_OK) {
+ return SL_STATUS_TRANSMIT;
+ }
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Multi-byte SPI transaction (receive).
+ ******************************************************************************/
+sl_status_t sdc_rcvr_spi_multi(SPIDRV_Handle_t spi_handle,
+ uint8_t *buff,
+ uint16_t cnt)
+{
+ sl_status_t retval;
+ uint8_t dummy = 0xff;
+
+ if (!spi_handle) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+ retval = SPIDRV_MTransferB(spi_handle, &dummy, buff, cnt);
+ if (retval != ECODE_EMDRV_SPIDRV_OK) {
+ return SL_STATUS_TRANSMIT;
+ }
+
+ return SL_STATUS_OK;
+}
+
+sl_status_t sdc_platform_set_bit_rate(SPIDRV_Handle_t spi_handle,
+ uint32_t bit_rate)
+{
+ sl_status_t retval;
+
+ if (!spi_handle) {
+ return SL_STATUS_NULL_POINTER;
+ }
+
+ retval = SPIDRV_SetBitrate(spi_handle, bit_rate);
+
+ if (retval != ECODE_EMDRV_SPIDRV_OK) {
+ return SL_STATUS_TRANSMIT;
+ }
+
+ return SL_STATUS_OK;
+}
diff --git a/driver/public/silabs/ir_array_amg88xx/config/brd2601b/sl_i2cspm_qwiic_config.h b/driver/public/silabs/ir_array_amg88xx/config/brd2601b/sl_i2cspm_qwiic_config.h
new file mode 100644
index 00000000..6617d37f
--- /dev/null
+++ b/driver/public/silabs/ir_array_amg88xx/config/brd2601b/sl_i2cspm_qwiic_config.h
@@ -0,0 +1,57 @@
+/***************************************************************************//**
+ * @file
+ * @brief I2CSPM Config
+ *******************************************************************************
+ * # License
+ * Copyright 2019 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+
+#ifndef SL_I2CSPM_QWIIC_CONFIG_H
+#define SL_I2CSPM_QWIIC_CONFIG_H
+
+// <<< Use Configuration Wizard in Context Menu
+
+// I2CSPM settings
+
+// Reference clock frequency
+// Frequency in Hz of the reference clock.
+// Select 0 to use the frequency of the currently selected clock.
+// Default: 0
+#define SL_I2CSPM_QWIIC_REFERENCE_CLOCK 0
+
+// Speed mode
+// <0=> Standard mode (100kbit/s)
+// <1=> Fast mode (400kbit/s)
+// <2=> Fast mode plus (1Mbit/s)
+// Default: 0
+#define SL_I2CSPM_QWIIC_SPEED_MODE 0
+// end I2CSPM config
+
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+// SL_I2CSPM_QWIIC
+// $[I2C_SL_I2CSPM_QWIIC]
+#define SL_I2CSPM_QWIIC_PERIPHERAL I2C0
+#define SL_I2CSPM_QWIIC_PERIPHERAL_NO 0
+
+// I2C0 SCL on PC06
+#define SL_I2CSPM_QWIIC_SCL_PORT gpioPortC
+#define SL_I2CSPM_QWIIC_SCL_PIN 4
+
+// I2C0 SDA on PC05
+#define SL_I2CSPM_QWIIC_SDA_PORT gpioPortC
+#define SL_I2CSPM_QWIIC_SDA_PIN 5
+// [I2C_SL_I2CSPM_QWIIC]$
+// <<< sl:end pin_tool >>>
+
+#endif // SL_I2CSPM_QWIIC_CONFIG_H
diff --git a/driver/public/silabs/ir_array_amg88xx/inc/ir_array_amg88xx.h b/driver/public/silabs/ir_array_amg88xx/inc/ir_array_amg88xx.h
new file mode 100644
index 00000000..302f910e
--- /dev/null
+++ b/driver/public/silabs/ir_array_amg88xx/inc/ir_array_amg88xx.h
@@ -0,0 +1,487 @@
+/***************************************************************************//**
+ * @file ir_array_amg88xx.h
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef IR_ARRAY_AMG88XX_H_
+#define IR_ARRAY_AMG88XX_H_
+
+#include "sl_status.h"
+#include "sl_i2cspm.h"
+
+// -----------------------------------------------------------------------------
+// Defines
+// -----------------------------------------------------------------------------
+
+/***************************************************************************//**
+ * Dimensions of the sensor array.
+ ******************************************************************************/
+#define SENSOR_ARRAY_ROWS 8
+#define SENSOR_ARRAY_COLUMNS 8
+
+#define I2C_BUFFER_SIZE 10
+
+/***************************************************************************//**
+ * For detailed description for the following registers see the datasheet.
+ ******************************************************************************/
+#define AMG88XX_ADDRESS_OPEN 0x69
+#define AMG88XX_ADDRESS_CLOSE 0x68
+
+#define POWER_CONTROL_REGISTER 0x00
+#define RESET_REGISTER 0x01
+#define FRAMERATE_REGISTER 0x02
+#define INT_CONTROL_REGISTER 0x03
+#define STATUS_REGISTER 0x04
+#define STATUS_CLEAR_REGISTER 0x05
+#define AVERAGE_REGISTER 0x07
+#define INT_LEVEL_REGISTER_UPPER_LSB 0x08
+#define INT_LEVEL_REGISTER_UPPER_MSB 0x09
+#define INT_LEVEL_REGISTER_LOWER_LSB 0x0A
+#define INT_LEVEL_REGISTER_LOWER_MSB 0x0B
+#define INT_LEVEL_REGISTER_HYST_LSB 0x0C
+#define INT_LEVEL_REGISTER_HYST_MSB 0x0D
+#define THERMISTOR_REGISTER_LSB 0x0E
+#define THERMISTOR_REGISTER_MSB 0x0F
+#define INT_TABLE_REGISTER_INT0 0x10
+#define RESERVED_AVERAGE_REGISTER 0x1F
+#define TEMPERATURE_REGISTER_START 0x80
+
+// -----------------------------------------------------------------------------
+// Variable declarations
+// -----------------------------------------------------------------------------
+enum temperature_scale_t{CELSIUS,
+ FAHRENHEIT};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * Initialise the periphery
+ *
+ * @param i2c The used I2C instance.
+ * @param I2C_address The used device address.
+ * @param temp_scale Temperature scale. Can be "celsius" or "fahrenheit".
+ ******************************************************************************/
+void amg88xx_init(sl_i2cspm_t *amg88xx_i2c_instance_init,
+ int16_t I2C_address,
+ enum temperature_scale_t temp_scale);
+
+/***************************************************************************//**
+ * Sets temperature scale for temperature related functions.
+ * The scale is initialized to celsius by default.
+ *
+ * @param temp_scale Temperature scale. Can be "celsius" or "fahrenheit".
+ ******************************************************************************/
+void set_temperature_scale(enum temperature_scale_t temp_scale);
+
+/***************************************************************************//**
+ * Gets the thermistor temperature.
+ * The temperature scale can be set globally with set_temperature_scale().
+ *
+ * @param thermistor_temperature Temperature of the thermistor.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_thermistor_temperature(float *thermistor_temperature);
+
+/***************************************************************************//**
+ * Gets the raw thermistor temperature.
+ *
+ * @param thermistor_temperature Raw temperature of the device.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_thermistor_temperature_raw(
+ int16_t *thermistor_temperature);
+
+/***************************************************************************//**
+ * Gets the temperature of a single pixel.
+ * The temperature scale can be set globally with set_temperature_scale().
+ * For the pixel map check the amg88xx datasheet:
+ * https://industrial.panasonic.com/cdbs/www-data/pdf/ADI8000/ADI8000C66.pdf
+ *
+ * @param pixel_number # of the pixel in order as in the registers. (0-63)
+ * @param pixel_temperature Temperature of the pixel identified by pixel_number
+ * in celsius.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_pixel_temperature(unsigned char pixelAddr,
+ float *pixel_temperature);
+
+/*******************************************************************************
+ * Gets the raw temperature value of a single pixel.
+ * For the pixel map check the amg88xx datasheet:
+ * https://industrial.panasonic.com/cdbs/www-data/pdf/ADI8000/ADI8000C66.pdf
+ *
+ * @param pixel_number # of the pixel in order as in the registers. (0-63)
+ * @param pixel_temperature Raw temperature of the pixel identified by
+ * pixel_number.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_pixel_temperature_raw(unsigned char pixelAddr,
+ int16_t *raw_pixel_temperature);
+
+/***************************************************************************//**
+ * Gets the temperatures of the IR sensor array.
+ * The temperature scale can be set globally with set_temperature_scale().
+ * For the pixel map check the amg88xx datasheet:
+ * https://industrial.panasonic.com/cdbs/www-data/pdf/ADI8000/ADI8000C66.pdf
+ *
+ * @param temperature_grid Array of temperatures.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_sensor_array_temperatures(
+ float temperature_grid[SENSOR_ARRAY_COLUMNS][SENSOR_ARRAY_ROWS]);
+
+/***************************************************************************//**
+ * Gets the raw temperatures of the IR sensor array.
+ * For the pixel map check the amg88xx datasheet:
+ * https://industrial.panasonic.com/cdbs/www-data/pdf/ADI8000/ADI8000C66.pdf
+ *
+ * @param temperature_grid Array of temperatures.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_sensor_array_temperatures_raw(
+ uint16_t temperature_grid[SENSOR_ARRAY_COLUMNS][SENSOR_ARRAY_ROWS]);
+
+/***************************************************************************//**
+ * Sets the I2C address of the amg88xx.
+ *
+ * @param address i2c address of the amg88xx
+ ******************************************************************************/
+void amg88xx_set_i2c_address(uint16_t address);
+
+/***************************************************************************//**
+ * Puts the device to normal mode from any other state.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_wake(void);
+
+/***************************************************************************//**
+ * Puts device into sleep mode.
+ * Temperature registers are not updated.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_sleep(void);
+
+/***************************************************************************//**
+ * Puts the device into 60 sec update interval mode.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_60_sec_standby(void);
+
+/***************************************************************************//**
+ * Puts the device into 10 sec update interval mode.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_10_sec_standby(void);
+
+/***************************************************************************//**
+ * Enable INT pin to pull low on interrupt flag.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_interrupt_pin_enable(void);
+
+/***************************************************************************//**
+ * Put INT pin into Hi-Z state.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_interrupt_pin_disable(void);
+
+/***************************************************************************//**
+ * Set interrupt mode to "Absolute Value" mode.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_set_interrupt_mode_absolute(void);
+
+/***************************************************************************//**
+ * Set interrupt mode to "Difference" mode.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_set_interrupt_mode_difference(void);
+
+/***************************************************************************//**
+ * is_enabled will be true if the INT pin is enabled.
+ * False if INT pin is in Hi-Z.
+ *
+ * @param is_enabled True if the interrupt pin enabled, false otherwise.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_is_interrupt_pin_enabled(bool *is_enabled);
+
+/***************************************************************************//**
+ * is_set will be true,
+ * if there is an interrupt flag in the status register.
+ *
+ * @param is_set True, if the interrupt flag is set, false otherwise.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_is_interrupt_flag_set(bool *is_set);
+
+/***************************************************************************//**
+ * is_set will be false, if temperature output overflow
+ * flag is present in status register.
+ *
+ * @param is_set True if the temperature output overflow flag is set.
+ * False otherwise.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_is_temperature_output_overflow_flag_set(bool *is_set);
+
+/***************************************************************************//**
+ * is_set will be false, if thermistor output overflow
+ * flag is present in status register.
+ *
+ * @param is_set True if the thermistor output overflow flag is set.
+ * False otherwise.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_is_thermistor_output_overflow_flag_set(bool *is_set);
+
+/***************************************************************************//**
+ * Clears interrupt flag in the status register.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_clear_interrupt_flag(void);
+
+/***************************************************************************//**
+ * Clears temperature output overflow flag
+ * in the status register.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_clear_temperature_output_overflow_flag(void);
+
+/***************************************************************************//**
+ * Clears thermistor output overflow flag
+ * in status register.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_clear_thermistor_output_overflow_flag(void);
+
+/***************************************************************************//**
+ * Clears both thermistor and
+ * temperature overflow flags in the status register,
+ * but leaves interrupt flag untouched.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_clear_all_overflow(void);
+
+/***************************************************************************//**
+ * Clears all flags in the status register.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_clear_all_status_flags(void);
+
+/***************************************************************************//**
+ * Reads the interrupt table register.
+ * is_set will be true if interrupt flag is set
+ * for the specified pixel
+ * For the pixel map check the amg88xx datasheet:
+ * https://industrial.panasonic.com/cdbs/www-data/pdf/ADI8000/ADI8000C66.pdf
+ *
+ * @param pixel_number # of the pixel in order as in the registers (0-63)
+ * @param is_set True, if the interrupt is set for the pixel determined by
+ * pixel_number. False otherwise.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_is_pixel_interrupt_set(uint8_t pixelAddr, bool *is_set);
+
+/***************************************************************************//**
+ * Enable "Twice Moving Average".
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_enable_moving_average(void);
+
+/***************************************************************************//**
+ * Disable "Twice Moving Average".
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_disable_moving_average(void);
+
+/***************************************************************************//**
+ * is_enabled will be true, if "Twice Moving Average"
+ * is enabled.
+ *
+ * @param is_enabled True, if moving average enabled.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_is_moving_average_enabled(bool *is_enabled);
+
+/***************************************************************************//**
+ * Sets upper interrupt temperature.
+ * The temperature scale can be set globally with set_temperature_scale().
+ *
+ * @param degrees Desired value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_set_upper_interrupt_value(float degrees);
+
+/***************************************************************************//**
+ * Sets upper interrupt temperature.
+ *
+ * @param register_value Desired raw temperature value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_set_upper_interrupt_value_raw(int16_t register_value);
+
+/***************************************************************************//**
+ * Sets lower interrupt temperature.
+ * The temperature scale can be set globally with set_temperature_scale().
+ *
+ * @param degrees Desired value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_set_lower_interrupt_value(float degrees);
+
+/***************************************************************************//**
+ * Sets lower interrupt temperature.
+ *
+ * @param register_value Desired raw value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_set_lower_interrupt_value_raw(int16_t register_value);
+
+/***************************************************************************//**
+ * Sets interrupt hysteresis temperature.
+ * The temperature scale can be set globally with set_temperature_scale().
+ *
+ * @param degrees Desired value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_set_interrupt_hysteresis(float degrees);
+
+/***************************************************************************//**
+ * Sets interrupt hysteresis temperature.
+ *
+ * @param register_value Raw desired value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_set_interrupt_hysteresis_raw(int16_t register_value);
+
+/***************************************************************************//**
+ * Sets upper interrupt temperature.
+ * The temperature scale can be set globally with set_temperature_scale().
+ *
+ * @param degrees Temperature value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_upper_interrupt_value(float *degrees);
+
+/***************************************************************************//**
+ * Gets upper interrupt temperature.
+ *
+ * @param register_value Raw temperature value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_upper_interrupt_value_raw(int16_t *register_value);
+
+/***************************************************************************//**
+ * Sets lower interrupt temperature.
+ * The temperature scale can be set globally with set_temperature_scale().
+ *
+ * @param degrees Temperature value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_lower_interrupt_value(float *degrees);
+
+/***************************************************************************//**
+ * Gets lower interrupt temperature.
+ *
+ * @param register_value Raw temperature value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_lower_interrupt_value_raw(int16_t *register_value);
+
+/***************************************************************************//**
+ * Gets interrupt hysteresis temperature.
+ * The temperature scale can be set globally with set_temperature_scale().
+ *
+ * @param degrees Temperature value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_interrupt_hysteresis(float *degrees);
+
+/***************************************************************************//**
+ * Gets interrupt hysteresis temperature.
+ *
+ * @param register_value Raw temperature value.
+ *
+ * @returns The result of the I2C transaction.
+ ******************************************************************************/
+sl_status_t amg88xx_get_interrupt_hysteresis_raw(int16_t *register_value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IR_ARRAY_AMG88XX_DRIVER_H_
diff --git a/driver/public/silabs/ir_array_amg88xx/src/ir_array_amg88xx.c b/driver/public/silabs/ir_array_amg88xx/src/ir_array_amg88xx.c
new file mode 100644
index 00000000..11c169dc
--- /dev/null
+++ b/driver/public/silabs/ir_array_amg88xx/src/ir_array_amg88xx.c
@@ -0,0 +1,821 @@
+/***************************************************************************//**
+ * @file ir_array_amg88xx.c
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+#include
+#include
+#include
+#include
+#include "em_gpio.h"
+#include "em_cmu.h"
+#include "sl_status.h"
+#include "ir_array_amg88xx.h"
+
+// -----------------------------------------------------------------------------
+// Local Variables
+// -----------------------------------------------------------------------------
+static uint16_t amg88xx_I2C_address = AMG88XX_ADDRESS_OPEN;
+
+static enum temperature_scale_t temperature_scale = CELSIUS;
+
+static sl_i2cspm_t *amg88xx_I2C_instance = NULL;
+
+// -----------------------------------------------------------------------------
+// Local Functions
+// -----------------------------------------------------------------------------
+
+/***************************************************************************//**
+ * Read numBytes from the amg88xx trough i2c starting at register_address.
+ *
+ * @param register_address The address of a register contained by the target
+ * i2c device.
+ * @param rx_buffer The data read from the i2c device will be stored here.
+ * @param number_of_bytes Number of bytes will be read from the i2c device.
+ *
+ * @returns The result of the transaction.
+ ******************************************************************************/
+static sl_status_t amg88xx_i2c_read(uint8_t register_address,
+ uint8_t *rx_buffer,
+ uint8_t number_of_bytes)
+{
+ // Transfer structure.
+ I2C_TransferSeq_TypeDef i2c_transfer;
+ I2C_TransferReturn_TypeDef result;
+
+ // Initializing I2C transfer.
+ i2c_transfer.addr = (uint16_t) (amg88xx_I2C_address << 1);
+ // Must write target address before reading.
+ i2c_transfer.flags = I2C_FLAG_WRITE_READ;
+ i2c_transfer.buf[0].data = ®ister_address;
+ i2c_transfer.buf[0].len = 1;
+ i2c_transfer.buf[1].data = rx_buffer;
+ i2c_transfer.buf[1].len = number_of_bytes;
+
+ result = I2CSPM_Transfer(amg88xx_I2C_instance, &i2c_transfer);
+
+ if (result == i2cTransferDone) {
+ return SL_STATUS_OK;
+ } else {
+ return SL_STATUS_FAIL;
+ }
+}
+
+/***************************************************************************//**
+ * I2C write numBytes to the amg88xx trough i2c starting at register_address.
+ *
+ * @param register_address is the address of a register contained by the target
+ * i2c device
+ * @param tx_buffer the data to be write to the i2c device
+ * @param number_of_bytes number of bytes to be written to the i2c device
+ *
+ * @returns The result of the transaction.
+ ******************************************************************************/
+static sl_status_t amg88xx_i2c_write(uint8_t register_address,
+ const uint8_t *tx_buffer,
+ uint8_t number_of_bytes)
+{
+ // Transfer structure.
+ I2C_TransferSeq_TypeDef i2c_transfer;
+ I2C_TransferReturn_TypeDef result;
+ uint8_t tx_buffer_with_address[I2C_BUFFER_SIZE + 1];
+
+ // Register address to write to.
+ tx_buffer_with_address[0] = register_address;
+ for (uint8_t i = 0; i < number_of_bytes; i++) {
+ tx_buffer_with_address[i + 1] = tx_buffer[i];
+ }
+
+ // Initializing I2C transfer.
+ i2c_transfer.addr = (uint16_t) (amg88xx_I2C_address << 1);
+ i2c_transfer.flags = I2C_FLAG_WRITE;
+ i2c_transfer.buf[0].data = tx_buffer_with_address;
+ i2c_transfer.buf[0].len = number_of_bytes + 1;
+ i2c_transfer.buf[1].data = NULL;
+ i2c_transfer.buf[1].len = 0;
+
+ result = I2CSPM_Transfer(amg88xx_I2C_instance, &i2c_transfer);
+
+ if (result == i2cTransferDone) {
+ return SL_STATUS_OK;
+ } else {
+ return SL_STATUS_FAIL;
+ }
+}
+
+/***************************************************************************//**
+ * Converts raw temperature to celsius.
+ *
+ * @param temp Raw temperature.
+ *
+ * @returns The temperature in celsius.
+ ******************************************************************************/
+static float convert_raw_to_celsius(int16_t temperature)
+{
+ // Temperature is reported as 12-bit twos complement.
+ // Check if temperature is negative.
+ if (temperature & (1 << 11)) {
+ // if temperature is negative, mask out the sign byte and
+ // make the float negative
+ temperature &= ~(1 << 11);
+ temperature = temperature * -1;
+ }
+
+ return (float)(temperature * 0.25);
+}
+
+/***************************************************************************//**
+ * Converts raw temperature to fahrenheit.
+ *
+ * @param Temp raw temperature
+ *
+ * @returns The temperature in fahrenheit.
+ ******************************************************************************/
+static float convert_raw_to_fahrenheit(int16_t temperature)
+{
+ // temperature is reported as 12-bit twos complement
+ // check if temperature is negative
+ if (temperature & (1 << 11)) {
+ // if temperature is negative, mask out the sign byte and
+ // make the float negative
+ temperature &= ~(1 << 11);
+ temperature = temperature * -1;
+ }
+
+ return (float)((float)(temperature * 0.25) * 1.8 + 32);
+}
+
+/***************************************************************************//**
+ * Converts celsius to raw.
+ *
+ * @param degrees_C Temperature in celsius.
+ *
+ * @returns The temperature in raw format.
+ ******************************************************************************/
+static uint16_t convert_celsius_to_raw(float degrees_C)
+{
+ bool is_negative = false;
+
+ if (degrees_C < 0) {
+ degrees_C = (float)(degrees_C * -1.0);
+ is_negative = true;
+ }
+
+ uint16_t temperature = 0;
+ temperature = (uint16_t)roundf(degrees_C * 4);
+
+ if (is_negative) {
+ temperature |= (1 << 11);
+ }
+
+ return temperature;
+}
+
+/***************************************************************************//**
+ * Converts fahrenheit to raw.
+ *
+ * @param degrees_F Temperature in fahrenheit.
+ *
+ * @returns The temperature in raw format.
+ ******************************************************************************/
+static uint16_t convert_fahrenheit_to_raw(float degrees_F)
+{
+ float degrees_C = (float) ((degrees_F - 32) / 1.8);
+ return convert_celsius_to_raw(degrees_C);
+}
+
+// -----------------------------------------------------------------------------
+// Global Functions
+// -----------------------------------------------------------------------------
+
+/***************************************************************************//**
+ * Initialise the periphery
+ ******************************************************************************/
+void amg88xx_init(sl_i2cspm_t *amg88xx_i2c_instance_init,
+ int16_t I2C_address,
+ enum temperature_scale_t temp_scale)
+{
+ amg88xx_I2C_instance = amg88xx_i2c_instance_init;
+ amg88xx_I2C_address = I2C_address;
+ set_temperature_scale(temp_scale);
+}
+
+/***************************************************************************//**
+ * Sets temperature scale for temperature related functions.
+ ******************************************************************************/
+void set_temperature_scale(enum temperature_scale_t temp_scale)
+{
+ temperature_scale = temp_scale;
+}
+
+/***************************************************************************//**
+ * Get thermistor temperature.
+ ******************************************************************************/
+sl_status_t amg88xx_get_thermistor_temperature(float *thermistor_temperature)
+{
+ int16_t temperature = 0;
+ uint32_t read_result;
+ read_result = amg88xx_get_thermistor_temperature_raw(&temperature);
+ if (read_result == SL_STATUS_OK) {
+ // Temperature is reported as 12-bit twos complement.
+ // Check if temperature is negative.
+ if (temperature & (1 << 11)) {
+ // If temperature is negative, mask out the sign byte and
+ // make the float negative.
+ temperature &= ~(1 << 11);
+ temperature = temperature * -1;
+ }
+ *thermistor_temperature = (float) (temperature * 0.0625);
+ if (temperature_scale == FAHRENHEIT) {
+ *thermistor_temperature = (float) (*thermistor_temperature * 1.8 + 32);
+ }
+ }
+
+ return read_result;
+}
+
+sl_status_t amg88xx_get_thermistor_temperature_raw(
+ int16_t *raw_pixel_temperature)
+{
+ return amg88xx_i2c_read(THERMISTOR_REGISTER_LSB,
+ (void *)raw_pixel_temperature,
+ 2);
+}
+
+/***************************************************************************//**
+ * Get the temperature provided by a pixel.
+ ******************************************************************************/
+sl_status_t amg88xx_get_pixel_temperature(unsigned char pixel_number,
+ float *pixel_temperature)
+{
+ int16_t temperature = 0;
+ sl_status_t result = amg88xx_get_pixel_temperature_raw(pixel_number,
+ &temperature);
+ if (temperature_scale == CELSIUS) {
+ *pixel_temperature = convert_raw_to_celsius(temperature);
+ } else {
+ *pixel_temperature = convert_raw_to_fahrenheit(temperature);
+ }
+ return result;
+}
+
+sl_status_t amg88xx_get_pixel_temperature_raw(unsigned char pixel_number,
+ int16_t *raw_pixel_temperature)
+{
+ return amg88xx_i2c_read(TEMPERATURE_REGISTER_START + (2 * pixel_number),
+ (void *)raw_pixel_temperature,
+ 2);
+}
+
+/***************************************************************************//**
+ * Get the temperatures of the IR sensor array.
+ ******************************************************************************/
+sl_status_t amg88xx_get_sensor_array_temperatures(
+ float temperature_grid[SENSOR_ARRAY_COLUMNS][SENSOR_ARRAY_ROWS])
+{
+ uint8_t i = 0;
+ uint16_t temperature_grid_raw[SENSOR_ARRAY_COLUMNS][SENSOR_ARRAY_ROWS];
+ uint32_t read_result;
+ read_result = amg88xx_i2c_read(TEMPERATURE_REGISTER_START,
+ (void *)temperature_grid_raw,
+ SENSOR_ARRAY_ROWS * SENSOR_ARRAY_COLUMNS * 2);
+ while ((read_result == SL_STATUS_OK) && (i < SENSOR_ARRAY_COLUMNS)) {
+ for (int j = 0; j < SENSOR_ARRAY_ROWS; j++) {
+ if (temperature_scale == CELSIUS) {
+ temperature_grid[i][j] = convert_raw_to_celsius(
+ temperature_grid_raw[i][j]);
+ } else {
+ temperature_grid[i][j] = convert_raw_to_fahrenheit(
+ temperature_grid_raw[i][j]);
+ }
+ }
+ i++;
+ }
+
+ return read_result;
+}
+
+sl_status_t amg88xx_get_sensor_array_temperatures_raw(
+ uint16_t temperature_grid[SENSOR_ARRAY_COLUMNS][SENSOR_ARRAY_ROWS])
+{
+ return amg88xx_i2c_read(TEMPERATURE_REGISTER_START,
+ (void *)temperature_grid,
+ SENSOR_ARRAY_ROWS * SENSOR_ARRAY_COLUMNS
+ * 2);
+}
+
+/***************************************************************************//**
+ * Sets the I2C address of the amg88xx.
+ ******************************************************************************/
+void amg88xx_set_i2c_address(uint16_t address)
+{
+ amg88xx_I2C_address = address;
+}
+
+/***************************************************************************//**
+ * Returns device to normal mode from any other state.
+ ******************************************************************************/
+sl_status_t amg88xx_wake(void)
+{
+ uint8_t register_value = 0x00;
+ return amg88xx_i2c_write(POWER_CONTROL_REGISTER, ®ister_value, 1);
+}
+
+/***************************************************************************//**
+ * Puts device into sleep mode.
+ ******************************************************************************/
+sl_status_t amg88xx_sleep(void)
+{
+ uint8_t register_value = 0x10;
+ return amg88xx_i2c_write(POWER_CONTROL_REGISTER, ®ister_value, 1);
+}
+
+/***************************************************************************//**
+ * Puts the device into 60 sec update interval mode.
+ ******************************************************************************/
+sl_status_t amg88xx_60_sec_standby(void)
+{
+ uint8_t register_value = 0x20;
+ return amg88xx_i2c_write(POWER_CONTROL_REGISTER, ®ister_value, 1);
+}
+
+/***************************************************************************//**
+ * Puts the device into 10 sec update interval mode.
+ ******************************************************************************/
+sl_status_t amg88xx_10_sec_standby(void)
+{
+ uint8_t register_value = 0x21;
+ return amg88xx_i2c_write(POWER_CONTROL_REGISTER, ®ister_value, 1);
+}
+
+/***************************************************************************//**
+ * Functions for manipulating Interrupt Control Register.
+ ******************************************************************************/
+sl_status_t amg88xx_interrupt_pin_enable(void)
+{
+ uint8_t ICR_value;
+ sl_status_t read_result;
+ read_result = amg88xx_i2c_read(INT_CONTROL_REGISTER, &ICR_value, 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ ICR_value |= (1 << 0);
+ ICR_value &= 0xFF;
+ return amg88xx_i2c_write(INT_CONTROL_REGISTER, &ICR_value, 1);
+}
+
+sl_status_t amg88xx_interrupt_pin_disable(void)
+{
+ uint8_t ICR_value;
+ sl_status_t read_result;
+ read_result = amg88xx_i2c_read(INT_CONTROL_REGISTER, &ICR_value, 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ ICR_value &= ~(1 << 0);
+ ICR_value &= 0xFF;
+ return amg88xx_i2c_write(INT_CONTROL_REGISTER, &ICR_value, 1);
+}
+
+sl_status_t amg88xx_set_interrupt_mode_absolute(void)
+{
+ uint8_t ICR_value;
+ sl_status_t read_result;
+ read_result = amg88xx_i2c_read(INT_CONTROL_REGISTER, &ICR_value, 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ ICR_value |= (1 << 1);
+ ICR_value &= 0xFF;
+ return amg88xx_i2c_write(INT_CONTROL_REGISTER, &ICR_value, 1);
+}
+
+sl_status_t amg88xx_set_interrupt_mode_difference(void)
+{
+ uint8_t ICR_value;
+ sl_status_t read_result;
+ read_result = amg88xx_i2c_read(INT_CONTROL_REGISTER, &ICR_value, 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ ICR_value &= ~(1 << 1);
+ ICR_value &= 0xFF;
+ return amg88xx_i2c_write(INT_CONTROL_REGISTER, &ICR_value, 1);
+}
+
+sl_status_t amg88xx_is_interrupt_pin_enabled(bool *is_enabled)
+{
+ uint8_t ICR_value;
+ sl_status_t read_result;
+ read_result = amg88xx_i2c_read(INT_CONTROL_REGISTER, &ICR_value, 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ if (ICR_value & (1 << 0)) {
+ *is_enabled = true;
+ } else {
+ *is_enabled = false;
+ }
+
+ return read_result;
+}
+
+/***************************************************************************//**
+ * Functions for manipulating Status/Clear Registers.
+ ******************************************************************************/
+sl_status_t amg88xx_is_interrupt_flag_set(bool *is_set)
+{
+ uint8_t status_register_value;
+ sl_status_t read_result;
+ read_result = amg88xx_i2c_read(STATUS_REGISTER, &status_register_value, 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ if (status_register_value & (1 << 1)) {
+ *is_set = true;
+ } else {
+ *is_set = false;
+ }
+
+ return read_result;
+}
+
+sl_status_t amg88xx_is_temperature_output_overflow_flag_set(bool *is_set)
+{
+ uint8_t status_register_value;
+ sl_status_t read_result;
+ read_result = amg88xx_i2c_read(STATUS_REGISTER, &status_register_value, 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ if (status_register_value & (1 << 2)) {
+ *is_set = false;
+ } else {
+ *is_set = true;
+ }
+
+ return read_result;
+}
+
+sl_status_t amg88xx_is_thermistor_output_overflow_flag_set(bool *is_set)
+{
+ uint8_t status_register_value;
+ sl_status_t read_result;
+ read_result = amg88xx_i2c_read(STATUS_REGISTER, &status_register_value, 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ if (status_register_value & (1 << 3)) {
+ *is_set = false;
+ } else {
+ *is_set = true;
+ }
+
+ return read_result;
+}
+
+sl_status_t amg88xx_clear_interrupt_flag(void)
+{
+ uint8_t register_value = 0x02;
+ return amg88xx_i2c_write(STATUS_CLEAR_REGISTER, ®ister_value, 1);
+}
+
+sl_status_t amg88xx_clear_temperature_output_overflow_flag(void)
+{
+ uint8_t register_value = 0x04;
+ return amg88xx_i2c_write(STATUS_CLEAR_REGISTER, ®ister_value, 1);
+}
+
+sl_status_t amg88xx_clear_thermistor_output_overflow_flag(void)
+{
+ uint8_t register_value = 0x08;
+ return amg88xx_i2c_write(STATUS_CLEAR_REGISTER, ®ister_value, 1);
+}
+
+sl_status_t amg88xx_clear_all_overflow(void)
+{
+ uint8_t register_value = 0x0C;
+ return amg88xx_i2c_write(STATUS_CLEAR_REGISTER, ®ister_value, 1);
+}
+
+sl_status_t amg88xx_clear_all_status_flags(void)
+{
+ uint8_t register_value = 0x0E;
+ return amg88xx_i2c_write(STATUS_CLEAR_REGISTER, ®ister_value, 1);
+}
+
+/***************************************************************************//**
+ * Read Interrupt Table Register.
+ ******************************************************************************/
+sl_status_t amg88xx_is_pixel_interrupt_set(uint8_t pixel_number, bool *is_set)
+{
+ uint8_t interrupt_table_register = INT_TABLE_REGISTER_INT0
+ + (pixel_number / 8);
+ uint8_t pixel_position = (pixel_number % 8);
+
+ uint8_t interrupt_table_row;
+ sl_status_t read_result;
+ read_result = amg88xx_i2c_read(interrupt_table_register,
+ &interrupt_table_row,
+ 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ if (interrupt_table_row & (1 << pixel_position)) {
+ *is_set = true;
+ } else {
+ *is_set = false;
+ }
+
+ return read_result;
+}
+
+/***************************************************************************//**
+ * Functions for manipulating Average Register.
+ ******************************************************************************/
+sl_status_t amg88xx_enable_moving_average(void)
+{
+ sl_status_t read_result;
+
+ uint8_t register_value = 0x50;
+ read_result = amg88xx_i2c_write(RESERVED_AVERAGE_REGISTER,
+ ®ister_value,
+ 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ register_value = 0x45;
+ read_result = amg88xx_i2c_write(RESERVED_AVERAGE_REGISTER,
+ ®ister_value,
+ 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ register_value = 0x57;
+ read_result = amg88xx_i2c_write(RESERVED_AVERAGE_REGISTER,
+ ®ister_value,
+ 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ register_value = 0x20;
+ read_result = amg88xx_i2c_write(AVERAGE_REGISTER,
+ ®ister_value,
+ 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ register_value = 0x00;
+ read_result = amg88xx_i2c_write(RESERVED_AVERAGE_REGISTER,
+ ®ister_value,
+ 1);
+ return read_result;
+}
+
+sl_status_t amg88xx_disable_moving_average(void)
+{
+ sl_status_t read_result;
+
+ uint8_t register_value = 0x50;
+ read_result = amg88xx_i2c_write(RESERVED_AVERAGE_REGISTER,
+ ®ister_value,
+ 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ register_value = 0x45;
+ read_result = amg88xx_i2c_write(RESERVED_AVERAGE_REGISTER,
+ ®ister_value,
+ 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ register_value = 0x57;
+ read_result = amg88xx_i2c_write(RESERVED_AVERAGE_REGISTER,
+ ®ister_value,
+ 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ register_value = 0x00;
+ read_result = amg88xx_i2c_write(AVERAGE_REGISTER,
+ ®ister_value,
+ 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ register_value = 0x00;
+ read_result = amg88xx_i2c_write(RESERVED_AVERAGE_REGISTER,
+ ®ister_value,
+ 1);
+ return read_result;
+}
+
+sl_status_t amg88xx_is_moving_average_enabled(bool *is_enabled)
+{
+ uint8_t average_register_value;
+ sl_status_t read_result;
+ read_result = amg88xx_i2c_read(AVERAGE_REGISTER,
+ &average_register_value,
+ 1);
+ if (read_result != SL_STATUS_OK) {
+ return read_result;
+ }
+
+ if (average_register_value & (1 << 5)) {
+ *is_enabled = true;
+ } else {
+ *is_enabled = false;
+ }
+
+ return read_result;
+}
+
+/***************************************************************************//**
+ * Functions for manipulating Interrupt Level Register.
+ ******************************************************************************/
+sl_status_t amg88xx_set_upper_interrupt_value(float degrees)
+{
+ uint16_t temperature = 0;
+ if (temperature_scale == CELSIUS) {
+ temperature = convert_celsius_to_raw(degrees);
+ } else {
+ temperature = convert_fahrenheit_to_raw(degrees);
+ }
+
+ return amg88xx_i2c_write(INT_LEVEL_REGISTER_UPPER_LSB,
+ (void *)&temperature,
+ 2);
+}
+
+sl_status_t amg88xx_set_upper_interrupt_value_raw(int16_t register_value)
+{
+ return amg88xx_i2c_write(INT_LEVEL_REGISTER_UPPER_LSB,
+ (void *)®ister_value,
+ 2);
+}
+
+sl_status_t amg88xx_set_lower_interrupt_value(float degrees)
+{
+ uint16_t temperature = 0;
+ if (temperature_scale == CELSIUS) {
+ temperature = convert_celsius_to_raw(degrees);
+ } else {
+ temperature = convert_fahrenheit_to_raw(degrees);
+ }
+
+ return amg88xx_i2c_write(INT_LEVEL_REGISTER_LOWER_LSB,
+ (void *)&temperature,
+ 2);
+}
+
+sl_status_t amg88xx_set_lower_interrupt_value_raw(int16_t register_value)
+{
+ return amg88xx_i2c_write(INT_LEVEL_REGISTER_LOWER_LSB,
+ (void *)®ister_value,
+ 2);
+}
+
+sl_status_t amg88xx_set_interrupt_hysteresis(float degrees)
+{
+ uint16_t temperature = 0;
+ if (temperature_scale == CELSIUS) {
+ temperature = convert_celsius_to_raw(degrees);
+ } else {
+ temperature = convert_fahrenheit_to_raw(degrees);
+ }
+
+ return amg88xx_set_interrupt_hysteresis_raw(temperature);
+}
+
+sl_status_t amg88xx_set_interrupt_hysteresis_raw(int16_t register_value)
+{
+ return amg88xx_i2c_write(INT_LEVEL_REGISTER_HYST_LSB,
+ (void *)®ister_value,
+ 2);
+}
+
+sl_status_t amg88xx_get_upper_interrupt_value(float *degrees)
+{
+ int16_t temperature = 0;
+ sl_status_t result = amg88xx_get_upper_interrupt_value_raw(&temperature);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+
+ if (temperature_scale == CELSIUS) {
+ *degrees = convert_raw_to_celsius(temperature);
+ } else {
+ *degrees = convert_raw_to_fahrenheit(temperature);
+ }
+
+ return result;
+}
+
+sl_status_t amg88xx_get_upper_interrupt_value_raw(int16_t *register_value)
+{
+ return amg88xx_i2c_read(INT_LEVEL_REGISTER_UPPER_LSB,
+ (void *)register_value,
+ 2);
+}
+
+sl_status_t amg88xx_get_lower_interrupt_value(float *degrees)
+{
+ int16_t temperature = 0;
+ sl_status_t result = amg88xx_get_lower_interrupt_value_raw(&temperature);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+
+ if (temperature_scale == CELSIUS) {
+ *degrees = convert_raw_to_celsius(temperature);
+ } else {
+ *degrees = convert_raw_to_fahrenheit(temperature);
+ }
+
+ return result;
+}
+
+sl_status_t amg88xx_get_lower_interrupt_value_raw(int16_t *register_value)
+{
+ return amg88xx_i2c_read(INT_LEVEL_REGISTER_LOWER_LSB,
+ (void *)register_value,
+ 2);
+}
+
+sl_status_t amg88xx_get_interrupt_hysteresis(float *degrees)
+{
+ int16_t temperature = 0;
+ sl_status_t result = amg88xx_get_interrupt_hysteresis_raw(&temperature);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+
+ if (temperature_scale == CELSIUS) {
+ *degrees = convert_raw_to_celsius(temperature);
+ } else {
+ *degrees = convert_raw_to_fahrenheit(temperature);
+ }
+
+ return result;
+}
+
+sl_status_t amg88xx_get_interrupt_hysteresis_raw(int16_t *register_value)
+{
+ return amg88xx_i2c_read(INT_LEVEL_REGISTER_HYST_LSB,
+ (void *)register_value,
+ 2);
+}
diff --git a/driver/public/silabs/ir_generate/config/ir_generate_config.h b/driver/public/silabs/ir_generate/config/ir_generate_config.h
new file mode 100644
index 00000000..f08ab5af
--- /dev/null
+++ b/driver/public/silabs/ir_generate/config/ir_generate_config.h
@@ -0,0 +1,57 @@
+/***************************************************************************//**
+* @file ir_generate_config.h
+* @brief IR Generate Driver Configuration
+********************************************************************************
+* # License
+* Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+********************************************************************************
+*
+* SPDX-License-Identifier: Zlib
+*
+* The licensor of this software is Silicon Laboratories Inc.
+*
+* This software is provided \'as-is\', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*
+*******************************************************************************
+* # Evaluation Quality
+* This code has been minimally tested to ensure that it builds and is suitable
+* as a demonstration for evaluation purposes only. This code will be maintained
+* at the sole discretion of Silicon Labs.
+*******************************************************************************/
+#ifndef IR_GENERATE_CONFIG_H_
+#define IR_GENERATE_CONFIG_H_
+
+// <<< Use Configuration Wizard in Context Menu >>>
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// IR_GENERATE_BSP_CARRIER
+// $[GPIO_IR_GENERATE_BSP_CARRIER]
+#define IR_GENERATE_BSP_CARRIER_PORT gpioPortD
+#define IR_GENERATE_BSP_CARRIER_PIN 2
+// [GPIO_IR_GENERATE_BSP_CARRIER]$
+
+// IR_GENERATE_BSP_MODULATION
+// $[GPIO_IR_GENERATE_BSP_MODULATION]
+#define IR_GENERATE_BSP_MODULATION_PORT gpioPortD
+#define IR_GENERATE_BSP_MODULATION_PIN 3
+// [GPIO_IR_GENERATE_BSP_MODULATION]$
+
+// <<< sl:end pin_tool >>>
+
+#endif /* IR_GENERATE_CONFIG_H_ */
diff --git a/driver/public/silabs/ir_generate/inc/ir_generate.h b/driver/public/silabs/ir_generate/inc/ir_generate.h
new file mode 100644
index 00000000..58c2c570
--- /dev/null
+++ b/driver/public/silabs/ir_generate/inc/ir_generate.h
@@ -0,0 +1,126 @@
+/***************************************************************************//**
+ * @file ir_generate.h
+ * @brief IR Generator driver, APIs.
+ * @version 0.0.1
+ *******************************************************************************
+ * # License
+ * Copyright 2018 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+#ifndef __IRGENELATE_H__
+
+/***************************************************************************//**
+ * @addtogroup IR Generator Driver
+ * @brief IR Generator Driver
+ * . . . enter description here
+ * @{
+ ******************************************************************************/
+
+#define __IRGENELATE_H__
+#include "em_gpio.h"
+#include "em_timer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------
+ * define / Typedef
+ *----------------------------------------------*/
+
+#define TABLE_INDEX_NUM 18
+#define NEC_REPEAT_HEAD_SPACE_BIT_SIZE 4
+#define BIT(n) (1 << n)
+#define STREAM_BIT_NUM (200)
+
+typedef enum {
+ CODE_NEC,
+ CODE_SONY,
+ CODE_NUM
+}code_t;
+
+typedef enum {
+ HEAD_PULSE,
+ HEAD_SPACE,
+ HEAD_NUM
+}head_t;
+
+typedef struct {
+ code_t code;
+ uint16_t carrier[CODE_NUM];
+ uint16_t timebase[CODE_NUM];
+ float dutycycle[CODE_NUM];
+ uint8_t head_bit_size[CODE_NUM][HEAD_NUM];
+ uint8_t address_length[CODE_NUM];
+ uint8_t command_length[CODE_NUM];
+
+ uint8_t index;
+ uint8_t stream_index;
+ bool stream_active;
+ bool stream[STREAM_BIT_NUM];
+}ir_t;
+
+typedef void (*ir_callback_t)(void);
+
+/*----------------------------------------------
+ * prototype
+ *----------------------------------------------*/
+extern const uint8_t ir_table[TABLE_INDEX_NUM][2];
+
+/**
+ * @brief Initializes IR generation with IR code/protocol.
+ *
+ * @param ir_code instance of ir_generate_init to initialize
+ *
+ * @return none
+ *
+ */
+extern void ir_generate_init(code_t ir_code, ir_callback_t cb);
+
+/**
+ * @brief stop ir signal generate.
+ *
+ * @param none
+ *
+ * @return none
+ *
+ */
+extern void ir_generate_stop(void);
+
+/**
+ * @brief configure ir signal stream.
+ *
+ * @param none
+ *
+ * @return none
+ *
+ */
+extern void ir_generate_stream(uint16_t address, uint16_t command, bool repeat);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} (end addtogroup IR Generator Driver) */
+#endif
diff --git a/driver/public/silabs/ir_generate/src/ir_generate.c b/driver/public/silabs/ir_generate/src/ir_generate.c
new file mode 100644
index 00000000..b46a251d
--- /dev/null
+++ b/driver/public/silabs/ir_generate/src/ir_generate.c
@@ -0,0 +1,357 @@
+/***************************************************************************//**
+ * @file ir_generate.c
+ * @brief IR Generator driver, APIs.
+ * @version 0.0.1
+ *******************************************************************************
+ * # License
+ * Copyright 2018 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+#include "em_device.h"
+#include "em_cmu.h"
+#include "em_emu.h"
+#include "em_chip.h"
+#include "em_gpio.h"
+#include "em_prs.h"
+#include "ir_generate.h"
+#include "ir_generate_config.h"
+
+const uint8_t ir_table[TABLE_INDEX_NUM][2] = {
+ { 0x00, 0x00 },
+ { 0x2A, 0x15 }, // SONY Projector [POWER]
+ { 0x2A, 0x57 }, // SONY Projector [INPUT]
+ { 0x46, 0x44 },
+ { 0x47, 0x39 },
+ { 0x1C, 0x1C },
+ { 0x1B, 0x1B },
+ { 0x44, 0x44 },
+ { 0x12, 0x12 },
+ { 0x13, 0x13 },
+ { 0x46, 0x44 },
+ { 0x47, 0x39 },
+ { 0x1C, 0x1C },
+ { 0x1B, 0x1B },
+ { 0x44, 0x44 },
+ { 0x46, 0x44 },
+ { 0x47, 0x39 },
+ { 0x45, 0x45 }
+};
+
+static ir_t ir = {
+ .code = CODE_NEC,
+ .carrier = { 38000, 40000 },
+ .timebase = { 1769, 1659 },
+ .dutycycle = { 0.335, 0.335 },
+ .head_bit_size = { { 16, 8 }, { 4, 1 } },
+ .address_length = { 8, 7 },
+ .command_length = { 8, 8 },
+ .stream_active = false,
+ .stream_index = 0,
+};
+
+static ir_callback_t ir_complete_callback = 0;
+
+__STATIC_INLINE void ir_generate_stream_head(bool *stream, bool repeat)
+{
+ uint8_t i;
+ uint8_t spaceSize = ir.head_bit_size[ir.code][HEAD_SPACE];
+
+ if ((repeat == true) && (ir.code == CODE_NEC)) {
+ spaceSize = NEC_REPEAT_HEAD_SPACE_BIT_SIZE; // 2.25ms for repeat stream
+ }
+
+ // pulse, NEC: 16 for 9ms, SONY: 4 for 2.4ms
+ for (i = 0; i < ir.head_bit_size[ir.code][HEAD_PULSE]; i++) {
+ stream[ir.index++] = true;
+ }
+
+ // space, NEC: 8 for 4.5ms, SONY: 1 for 0.6ms
+ for (i = 0; i < spaceSize; i++) {
+ stream[ir.index++] = false;
+ }
+}
+
+__STATIC_INLINE void ir_generate_stream_logic(bool *stream, bool bit)
+{
+ bool *start_point = stream;
+ switch (ir.code) {
+ case CODE_NEC:
+ // 1(1 pulse, 3 spaces),0(1 pulse, 1 space)
+ *stream++ = true;
+ *stream++ = false;
+ if (bit) {
+ *stream++ = false;
+ *stream++ = false;
+ }
+ break;
+
+ case CODE_SONY:
+ // 1(2 pulse, 1 spaces), 0(1 pulse, 1 space)
+ *stream++ = true;
+ if (bit) {
+ *stream++ = true;
+ }
+ *stream++ = false;
+ break;
+
+ default:
+ *stream = false;
+ break;
+ }
+ ir.index += (stream - start_point);
+}
+
+__STATIC_INLINE void ir_generate_stream_byte(uint16_t stream_data,
+ uint8_t length)
+{
+ // NEC, SONY send in LSB
+ for (uint8_t i = 0; i < length; i++) {
+ ir_generate_stream_logic(&ir.stream[ir.index], (stream_data & BIT(0)));
+ stream_data >>= 1; // move left to get next bit
+ }
+}
+
+/**
+ * @brief configure ir signal stream.
+ *
+ * @param address, command, repeat flag for NEC protocol
+ *
+ * @return none
+ *
+ */
+void ir_generate_stream(uint16_t address, uint16_t command, bool repeat)
+{
+ while (ir.stream_active) { // Wait until done transmitting last code
+ }
+ ir.index = 0;
+ ir_generate_stream_head(&ir.stream[ir.index], repeat);
+ switch (ir.code) {
+ case CODE_NEC:
+ // address -> address complemented -> command -> command complemented
+ if (repeat == false) {
+ ir_generate_stream_byte(address, ir.address_length[ir.code]);
+ ir_generate_stream_byte((~address), ir.address_length[ir.code]);
+ ir_generate_stream_byte(command, ir.command_length[ir.code]);
+ ir_generate_stream_byte((~command), ir.command_length[ir.code]);
+ }
+ // Send trailing (pulse)
+ ir.stream[ir.index++] = true;
+ break;
+
+ case CODE_SONY:
+ // command -> address
+ ir_generate_stream_byte(command, ir.command_length[ir.code]);
+ ir_generate_stream_byte(address, ir.address_length[ir.code]);
+ break;
+
+ default:
+ break;
+ }
+ ir.stream[ir.index] = false;
+
+ ir.stream_active = true; // Enable sending code
+ ir.stream_index = 0; // start from 0, stop when ir.stream_index >=
+ // ir.index
+
+ TIMER_Enable(TIMER1, true);
+}
+
+__STATIC_INLINE void ir_generate_send(void)
+{
+ // Clear flag for TIMER1 overflow interrupt
+ TIMER_IntClear(TIMER1, TIMER_IF_OF);
+
+ if (ir.stream_active) {
+ // Send a pulse
+ if (ir.stream[ir.stream_index]) {
+ TIMER_Enable(TIMER0, true);
+ GPIO_PinOutSet(IR_GENERATE_BSP_MODULATION_PORT,
+ IR_GENERATE_BSP_MODULATION_PIN);
+ } else {
+ // Send a space
+ TIMER_Enable(TIMER0, false);
+ GPIO_PinOutClear(IR_GENERATE_BSP_MODULATION_PORT,
+ IR_GENERATE_BSP_MODULATION_PIN);
+ }
+ ir.stream_index++;
+
+ // Done sending the stream
+ if (ir.stream_index >= ir.index) {
+ ir.stream_index = 0;
+ ir.stream_active = false;
+ }
+ } else {
+ // TIMER_Enable(TIMER0, false);
+ ir_generate_stop();
+ GPIO_PinOutClear(IR_GENERATE_BSP_MODULATION_PORT,
+ IR_GENERATE_BSP_MODULATION_PIN);
+ ir_complete_callback();
+ }
+}
+
+/**
+ * @brief stop ir signal generate.
+ *
+ * @param none
+ *
+ * @return none
+ *
+ */
+void ir_generate_stop(void)
+{
+ TIMER_Enable(TIMER0, false);
+ TIMER_Enable(TIMER1, false);
+}
+
+__STATIC_INLINE void ir_generate_pin(void)
+{
+ CMU_ClockEnable(cmuClock_GPIO, true);
+ GPIO_PinModeSet(IR_GENERATE_BSP_CARRIER_PORT,
+ IR_GENERATE_BSP_CARRIER_PIN,
+ gpioModePushPull,
+ 0);
+ GPIO_PinModeSet(IR_GENERATE_BSP_MODULATION_PORT,
+ IR_GENERATE_BSP_MODULATION_PIN,
+ gpioModePushPull,
+ 0);
+}
+
+#if 0 // no need a interrupt for change the duty cycle
+void TIMER0_IRQHandler(void)
+{
+ // Acknowledge the interrupt
+ uint32_t flags = TIMER_IntGet(TIMER0);
+ TIMER_IntClear(TIMER0, flags);
+
+ // Update CCVB to alter duty cycle starting next period
+ // TIMER_CompareBufSet(TIMER0, 0, (uint32_t)(topValue * dutyCycle));
+}
+
+#endif
+
+__STATIC_INLINE void ir_generate_carrier(void)
+{
+ uint32_t timerFreq = 0;
+ uint32_t topValue = 0;
+
+ CMU_ClockEnable(cmuClock_TIMER0, true);
+
+ // Initialize the timer
+ TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
+ // Configure TIMER0 Compare/Capture for output compare
+ TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;
+
+ // Use PWM mode, which sets output on overflow and clears on compare events
+ timerInit.prescale = timerPrescale1;
+ timerInit.enable = false;
+ timerCCInit.mode = timerCCModePWM;
+
+ // Configure but do not start the timer
+ TIMER_Init(TIMER0, &timerInit);
+
+ // Route Timer0 CC0 output to PC0
+ GPIO->TIMERROUTE[0].ROUTEEN = GPIO_TIMER_ROUTEEN_CC0PEN;
+ GPIO->TIMERROUTE[0].CC0ROUTE =
+ (IR_GENERATE_BSP_CARRIER_PORT << _GPIO_TIMER_CC0ROUTE_PORT_SHIFT)
+ | (IR_GENERATE_BSP_CARRIER_PIN <<
+ _GPIO_TIMER_CC0ROUTE_PIN_SHIFT);
+
+ // Configure CC Channel 0
+ TIMER_InitCC(TIMER0, 0, &timerCCInit);
+
+ // set PWM period
+ timerFreq = CMU_ClockFreqGet(cmuClock_TIMER0) / (timerInit.prescale + 1);
+ topValue = (timerFreq / ir.carrier[ir.code]);
+ // Set top value to overflow at the desired PWM_FREQ frequency
+ TIMER_TopSet(TIMER0, topValue);
+
+ // Set compare value for initial duty cycle
+ TIMER_CompareSet(TIMER0, 0, (uint32_t)(topValue * ir.dutycycle[ir.code]));
+
+#if 0 // no need to start here and no need a interrupt for change the duty
+ // cycle
+ // Start the timer
+ TIMER_Enable(TIMER0, true);
+
+ // Enable TIMER0 compare event interrupts to update the duty cycle
+ TIMER_IntEnable(TIMER0, TIMER_IEN_CC0);
+ NVIC_EnableIRQ(TIMER0_IRQn);
+#endif
+}
+
+void TIMER1_IRQHandler(void)
+{
+ // Acknowledge the interrupt
+ uint32_t flags = TIMER_IntGet(TIMER1);
+ TIMER_IntClear(TIMER1, flags);
+ ir_generate_send();
+}
+
+__STATIC_INLINE void ir_generate_timebase(void)
+{
+ uint32_t timerFreq = 0;
+
+ CMU_ClockEnable(cmuClock_TIMER1, true);
+
+ // Initialize the timer
+ TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
+ timerInit.prescale = timerPrescale1;
+ timerInit.enable = false;
+
+ // Configure but do not start the timer
+ TIMER_Init(TIMER1, &timerInit);
+
+ timerFreq = CMU_ClockFreqGet(cmuClock_TIMER1) / (timerInit.prescale + 1);
+ TIMER_TopSet(TIMER1, (timerFreq / ir.timebase[ir.code]));
+
+ // Start the timer
+ // TIMER_Enable(TIMER1, true);
+
+ // Enable TIMER1 compare event interrupts to update the duty cycle
+ TIMER_IntEnable(TIMER1, TIMER_IF_OF);
+ NVIC_EnableIRQ(TIMER1_IRQn);
+}
+
+__STATIC_INLINE void ir_generate_code(code_t ir_code)
+{
+ ir.code = ir_code;
+}
+
+/**
+ * @brief Initializes IR generation with IR code/protocol.
+ *
+ * @param ir_code instance of ir_generate_init to initialize
+ *
+ * @return none
+ *
+ */
+void ir_generate_init(code_t ir_code, ir_callback_t cb)
+{
+ ir_generate_code(ir_code);
+ ir_generate_pin();
+ ir_generate_carrier();
+ ir_generate_timebase();
+ // ir_generate_stream(0xFF, 0xFF, false); // for test
+ ir_complete_callback = cb;
+}
diff --git a/driver/public/silabs/nfctag2_nt3h2111/config/brd2703a/mikroe_nt3h2111_config.h b/driver/public/silabs/nfctag2_nt3h2111/config/brd2703a/mikroe_nt3h2111_config.h
new file mode 100644
index 00000000..3a841ce4
--- /dev/null
+++ b/driver/public/silabs/nfctag2_nt3h2111/config/brd2703a/mikroe_nt3h2111_config.h
@@ -0,0 +1,67 @@
+/***************************************************************************//**
+ * @file mikroe_nt3h2111_config.h
+ * @brief SCL MIKROE NT3H2111 Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef MIKROE_NT3H211_CONFIG_H_
+#define MIKROE_NT3H211_CONFIG_H_
+
+#include "em_gpio.h"
+
+// A CMSIS annotation block starts with the following line:
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// Connection
+// I2C Address <0-0xFF>
+// Default: 0xAA
+#define MIKROE_NT3H211_ADDR 0xAA
+//
+
+// The block ends with the following line or at the end of the file:
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// MIKROE_NT3H211_FD
+// $[GPIO_MIKROE_NT3H211_FD]
+#define MIKROE_NT3H211_FD_PORT gpioPortB
+#define MIKROE_NT3H211_FD_PIN 1
+// [GPIO_MIKROE_NT3H211_FD]$
+
+// <<< sl:end pin_tool >>>
+
+#endif /* MIKROE_NT3H211_CONFIG_H_ */
diff --git a/driver/public/silabs/nfctag2_nt3h2111/config/brd4108a/mikroe_nt3h2111_config.h b/driver/public/silabs/nfctag2_nt3h2111/config/brd4108a/mikroe_nt3h2111_config.h
new file mode 100644
index 00000000..04b707ac
--- /dev/null
+++ b/driver/public/silabs/nfctag2_nt3h2111/config/brd4108a/mikroe_nt3h2111_config.h
@@ -0,0 +1,67 @@
+/***************************************************************************//**
+ * @file mikroe_nt3h2111_config.h
+ * @brief SCL MIKROE NT3H2111 Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef MIKROE_NT3H211_CONFIG_H_
+#define MIKROE_NT3H211_CONFIG_H_
+
+#include "em_gpio.h"
+
+// A CMSIS annotation block starts with the following line:
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// Connection
+// I2C Address <0-0xFF>
+// Default: 0xAA
+#define MIKROE_NT3H211_ADDR 0xAA
+//
+
+// The block ends with the following line or at the end of the file:
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// MIKROE_NT3H211_FD
+// $[GPIO_MIKROE_NT3H211_FD]
+#define MIKROE_NT3H211_FD_PORT gpioPortB
+#define MIKROE_NT3H211_FD_PIN 3
+// [GPIO_MIKROE_NT3H211_FD]$
+
+// <<< sl:end pin_tool >>>
+
+#endif /* MIKROE_NT3H211_CONFIG_H_ */
diff --git a/driver/public/silabs/nfctag2_nt3h2111/config/brd4314a/mikroe_nt3h2111_config.h b/driver/public/silabs/nfctag2_nt3h2111/config/brd4314a/mikroe_nt3h2111_config.h
new file mode 100644
index 00000000..04b707ac
--- /dev/null
+++ b/driver/public/silabs/nfctag2_nt3h2111/config/brd4314a/mikroe_nt3h2111_config.h
@@ -0,0 +1,67 @@
+/***************************************************************************//**
+ * @file mikroe_nt3h2111_config.h
+ * @brief SCL MIKROE NT3H2111 Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef MIKROE_NT3H211_CONFIG_H_
+#define MIKROE_NT3H211_CONFIG_H_
+
+#include "em_gpio.h"
+
+// A CMSIS annotation block starts with the following line:
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// Connection
+// I2C Address <0-0xFF>
+// Default: 0xAA
+#define MIKROE_NT3H211_ADDR 0xAA
+//
+
+// The block ends with the following line or at the end of the file:
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// MIKROE_NT3H211_FD
+// $[GPIO_MIKROE_NT3H211_FD]
+#define MIKROE_NT3H211_FD_PORT gpioPortB
+#define MIKROE_NT3H211_FD_PIN 3
+// [GPIO_MIKROE_NT3H211_FD]$
+
+// <<< sl:end pin_tool >>>
+
+#endif /* MIKROE_NT3H211_CONFIG_H_ */
diff --git a/driver/public/silabs/nfctag2_nt3h2111/config/other/mikroe_nt3h2111_config.h b/driver/public/silabs/nfctag2_nt3h2111/config/other/mikroe_nt3h2111_config.h
new file mode 100644
index 00000000..f1082684
--- /dev/null
+++ b/driver/public/silabs/nfctag2_nt3h2111/config/other/mikroe_nt3h2111_config.h
@@ -0,0 +1,68 @@
+/***************************************************************************//**
+ * @file mikroe_nt3h2111_config.h
+ * @brief SCL MIKROE NT3H2111 Configuration
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef MIKROE_NT3H211_CONFIG_H_
+#define MIKROE_NT3H211_CONFIG_H_
+
+#include "em_gpio.h"
+
+// A CMSIS annotation block starts with the following line:
+// <<< Use Configuration Wizard in Context Menu >>>
+
+// Connection
+// I2C Address <0-0xFF>
+// Default: 0xAA
+#define MIKROE_NT3H211_ADDR 0xAA
+//
+
+// The block ends with the following line or at the end of the file:
+// <<< end of configuration section >>>
+
+// <<< sl:start pin_tool >>>
+
+// MIKROE_NT3H211_FD
+// $[GPIO_MIKROE_NT3H211_FD]
+#warning "FD GPIO not configured"
+// #define MIKROE_NT3H211_FD_PORT gpioPortB
+// #define MIKROE_NT3H211_FD_PIN 3
+// [GPIO_MIKROE_NT3H211_FD]$
+
+// <<< sl:end pin_tool >>>
+
+#endif /* MIKROE_NT3H211_CONFIG_H_ */
diff --git a/driver/public/silabs/nfctag2_nt3h2111/inc/mikroe_nt3h2111.h b/driver/public/silabs/nfctag2_nt3h2111/inc/mikroe_nt3h2111.h
new file mode 100644
index 00000000..df1e597b
--- /dev/null
+++ b/driver/public/silabs/nfctag2_nt3h2111/inc/mikroe_nt3h2111.h
@@ -0,0 +1,555 @@
+/***************************************************************************//**
+ * @file nt3h2111.h
+ * @brief APIs and types for high level NT3H2111 functionalities.
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#ifndef _MIKROE_NT3H2111_H_
+#define _MIKROE_NT3H2111_H_
+
+#include
+#include
+#include "sl_status.h"
+
+#include "mikroe_nt3h2111_i2c.h"
+#include "mikroe_nt3h2111_config.h"
+
+#define ENABLED 1
+#define DISABLED 0
+
+#define ON 1
+#define OFF 0
+
+#define NT3H2111__MEM_ADRR_I2C_ADDR 0
+#define NT3H2111_CONFIG_REG_ADDR 0x3A
+#define NT3H2111_SESSION_REG_ADDR 0xFE
+#define NT3H2111_MEM_BLOCK_START_SRAM 0xF8
+#define NT3H2111_MEM_SRAM_BLOCKS 4
+
+/// memory bit masks
+#define NT3H2111_NC_REG_MASK_I2C_RST_ON_OFF 0x80
+#define NT3H2111_NC_REG_MASK_PTHRU_ON_OFF 0x40
+#define NT3H2111_NC_REG_MASK_FD_OFF 0x30
+#define NT3H2111_NC_REG_MASK_FD_ON 0x0C
+#define NT3H2111_NC_REG_MASK_SRAM_MIRROR_ON_OFF 0x02
+#define NT3H2111_NC_REG_MASK_TRANSFER_DIR 0x01
+
+#define NT3H2111_REG_LOCK_MASK_CONF_BYTES_ACCESS_I2C 0x02
+#define NT3H2111_REG_LOCK_MASK_CONF_BYTES_ACCESS_RF 0x01
+
+#define NT3H2111_NS_REG_MASK_NDEF_DATA_READ 0x80
+#define NT3H2111_NS_REG_MASK_I2C_LOCKED 0x40
+#define NT3H2111_NS_REG_MASK_RF_LOCKED 0x20
+#define NT3H2111_NS_REG_MASK_SRAM_I2C_READY 0x10
+#define NT3H2111_NS_REG_MASK_SRAM_RF_READY 0x08
+#define NT3H2111_NS_REG_MASK_EEPROM_WR_ERR 0x04
+#define NT3H2111_NS_REG_MASK_EEPROM_WR_BUSY 0x02
+#define NT3H2111_NS_REG_MASK_RF_FIELD_PRESENT 0x01
+
+#define NT3H2111_BLOCK_SIZE 16
+#define NT3H2111_WRITE_DELAY_MS 10
+
+#define BIT7_MASK 0x80
+#define BIT6_MASK 0x40
+#define BIT5_MASK 0x20
+#define BIT4_MASK 0x10
+#define BIT3_MASK 0x08
+#define BIT2_MASK 0x04
+#define BIT1_MASK 0x02
+#define BIT0_MASK 0x01
+
+#define NT3H2111_REG_LOCKED 1
+#define NT3H2111_REG_UNLOCKED 0
+
+#define NT3H2111_NC_REG_NFCS_I2C_RST_ON_OFF_M BIT7_MASK
+#define NT3H2111_NC_REG_NFCS_I2C_RST_ON_OFF_SHIFT 7
+#define NT3H2111_NC_REG_PTHRU_ON_OFF_M BIT6_MASK
+#define NT3H2111_NC_REG_PTHRU_ON_OFF_SHIFT 6
+#define NT3H2111_NC_REG_FD_OFF_M (BIT5_MASK | BIT4_MASK)
+#define NT3H2111_NC_REG_FD_OFF_SHIFT 4
+#define NT3H2111_NC_REG_FD_ON_M (BIT3_MASK | BIT2_MASK)
+#define NT3H2111_NC_REG_FD_ON_SHIFT 2
+#define NT3H2111_NC_REG_SRAM_MIRROR_ON_OFF_M BIT1_MASK
+#define NT3H2111_NC_REG_SRAM_MIRROR_ON_OFF_SHIFT 1
+#define NT3H2111_NC_REG_TRANSFER_DIR_M BIT0_MASK
+#define NT3H2111_NC_REG_TRANSFER_DIR_SHIFT 0
+
+#define NT3H2111_I2C_CLOCK_STR_M BIT0_MASK
+#define NT3H2111_I2C_CLOCK_STR_SHIFT 0
+
+#define TRANSFER_DIR_I2C_TO_NFC 0
+#define TRANSFER_DIR_NFC_TO_I2C 1
+
+/***************************************************************************//**
+ * @addtogroup NT3H2111 Driver
+ * @brief NT3H2111 top level APIs and Types.
+ * @{
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// NT3H2111 configuration register addresses within memory block.
+typedef enum {
+ CONFIG_NC_REG = 0,
+ CONFIG_LAST_NDEF_BLOCK = 1,
+ CONFIG_SRAM_MIRROR_BLOCK = 2,
+ CONFIG_WDT_LS = 3,
+ CONFIG_WDT_MS = 4,
+ CONFIG_I2C_CLOCK_STR = 5,
+ CONFIG_REG_LOCK = 6
+} nt3h2111_config_reg_addr_t;
+
+// NT3H2111 session register addresses within memory block.
+typedef enum {
+ SESSION_NC_REG = 0,
+ SESSION_LAST_NDEF_BLOCK = 1,
+ SESSION_SRAM_MIRROR_BLOCK = 2,
+ SESSION_WDT_LS = 3,
+ SESSION_WDT_MS = 4,
+ SESSION_I2C_CLOCK_STR = 5,
+ SESSION_NS_REG = 6
+} nt3h2111_session_reg_addr_t;
+
+/// NC_REG type.
+/// Details please refer to NT3H2111_2211 datasheet Table 13 and 14.
+typedef struct {
+ bool nfcs_i2c_rst_on_off;
+ bool pthru_on_off;
+ uint8_t fd_off;
+ uint8_t fd_on;
+ bool sram_mirror_on_off;
+ bool transfer_dir;
+} nt3h2111_nc_reg_t;
+
+/// I2C_CLOCK_STR type.
+/// Details please refer to NT3H2111_2211 datasheet Table 13 and 14.
+typedef struct {
+ /* Status bit to show the number of negative PWD_AUTH attempts reached
+ * 0b: PWD_AUTH still possible
+ * 1b: PWD_AUTH locked
+ * Note: this field is only available in session register.
+ */
+ bool nrg_auth_reached;
+
+ /* Enables (1b) or disable (0b) the I2C clock stretching. */
+ bool i2c_clock_str;
+} nt3h2111_i2c_clock_str_t;
+
+/// REG_LOCK type.
+/// Details please refer to NT3H2111_2211 datasheet Table 13 and 14.
+typedef struct {
+ bool reg_lock_i2c;
+ bool reg_lock_nfc;
+} nt3h2111_reg_lock_t;
+
+/// NS_REG type.
+/// Detials please refer to NRAG I2C plus datasheet Table 14.
+typedef struct {
+ /* 1b: all data bytes read from the address specified in LAST_NDEF_BLOCK.
+ * Bit is reset to 0b when read. */
+ bool ndef_data_read;
+
+ /* 1b: Memory access is locked to the I2C interface. */
+ bool i2c_locked;
+
+ /* 1b: Memory access is locked to the NFC interface. */
+ bool rf_locked;
+
+ /* 1b: data is ready in SRAM buffer to be read by I2C. */
+ bool sram_i2c_ready;
+
+ /* 1b: data is ready in SRAM buffer to be read by NFC. */
+ bool sram_rf_ready;
+
+ /* 1b: HV voltage error during EEPROM write or erase cycle
+ * Needs to be written back via I2C to 0b to be cleared. */
+ bool eeprom_wr_err;
+
+ /* 1b: EEPROM write cycle in progress - access to EEPROM disabled.
+ * 0b: EEPROM access possible. */
+ bool eeprom_wr_busy;
+
+ /* 1b: NFC field is detected. */
+ bool rf_firld_present;
+} nt3h2111_i2c_ns_reg_t;
+
+/// Configuration register type.
+/// Details please refer to NT3H2111_2211 datasheet Table 13.
+typedef struct {
+ /* NC_REG. */
+ nt3h2111_nc_reg_t nc_reg;
+
+ /* LAST_NDEF_BLOCK: I2C block address of I2C block,
+ * which contains last byte(s) of stored NDEF message. */
+ uint8_t last_ndef_block;
+
+ /* SRAM_MIRROR_BLOCK: 2C block address of SRAM
+ * when mirrored into the User memory. */
+ uint8_t sram_mirror_block;
+
+ /* WDT_LS: Least Significant byte of watchdog time control register. */
+ uint8_t wdt_ls;
+
+ /* WDT_MS: Most Significant byte of watchdog time control register.
+ * When writing WDT_MS byte, the content of WDT_MS and WDT_LS gets
+ * active for the watchdog timer. */
+ uint8_t wdt_ms;
+
+ /* I2C_CLOCK_STR. */
+ nt3h2111_i2c_clock_str_t i2c_clock_str;
+
+ /* REG_LOCK. */
+ nt3h2111_reg_lock_t reg_lock;
+} nt3h2111_config_reg_t;
+
+/// Session register type.
+/// Details please refer to NT3H2111_2211 datasheet Table 14.
+typedef struct {
+ /* NC_REG. */
+ nt3h2111_nc_reg_t nc_reg;
+
+ /* LAST_NDEF_BLOCK: I2C block address of I2C block,
+ * which contains last byte(s) of stored NDEF message. */
+ uint8_t last_ndef_block;
+
+ /* SRAM_MIRROR_BLOCK: 2C block address of SRAM
+ * when mirrored into the User memory. */
+ uint8_t sram_mirror_block;
+
+ /* WDT_LS: Least Significant byte of watchdog time control register. */
+ uint8_t wdt_ls;
+
+ /* WDT_MS: Most Significant byte of watchdog time control register.
+ * When writing WDT_MS byte, the content of WDT_MS and WDT_LS gets
+ * active for the watchdog timer. */
+ uint8_t wdt_ms;
+
+ /* I2C_CLOCK_STR. */
+ nt3h2111_i2c_clock_str_t i2c_clock_str;
+
+ /* REG_LOCK. */
+ nt3h2111_i2c_ns_reg_t ns_reg;
+} nt3h2111_session_reg_t;
+
+/***************************************************************************//**
+ * @brief
+ * Initialize the NT3H2111 driver with the values provided in the
+ * config file.
+ *
+ * @param[in] i2cspm
+ * The I2CSPM instance to use.
+ *
+ * @return
+ * SL_STATUS_OK on success.
+ ******************************************************************************/
+sl_status_t nt3h2111_init(sl_i2cspm_t *i2cspm);
+
+/***************************************************************************//**
+ * @brief
+ * De-initialize the NT3H2111.
+ *
+ * @return
+ * SL_STATUS_OK on success.
+ ******************************************************************************/
+sl_status_t nt3h2111_deinit(void);
+
+/***************************************************************************//**
+ * @brief
+ * Read a configuration register in NT3H2111.
+ *
+ * @param[in] rega
+ * Register address within memory block
+ *
+ * @param[out] data
+ * Buffer output
+ *
+ * @returns
+ * Read result (data and any error code)
+ *
+ * @note
+ * Details for I2C configuration registers. Please refer to NT3H2111_2211
+ * product data sheet section 8.3.12.
+ *
+ ******************************************************************************/
+sl_status_t nt3h2111_get_config(nt3h2111_config_reg_addr_t rega, uint8_t *data);
+
+/***************************************************************************//**
+ * @brief
+ * Write to a configuration register in NT3H2111.
+ *
+ * @param[in] rega
+ * Register address within memory block
+ *
+ * @param[in] regd
+ * Register data to be written
+ *
+ * @returns
+ * Any error code
+ *
+ * @note
+ * Details for I2C configuration registers. Please refer to NT3H2111_2211
+ * product data sheet section 8.3.12.
+ *
+ ******************************************************************************/
+sl_status_t nt3h2111_set_config(nt3h2111_config_reg_addr_t rega,
+ uint8_t mask,
+ uint8_t regd);
+
+/**************************************************************************//**
+ * @brief
+ * Read a session register in NT3H2111.
+ *
+ * @param[in] rega
+ * Register address within memory block
+ *
+ * @param[out] data
+ * Buffer output
+ *
+ * @returns
+ * Read result (data and any error code)
+ *
+ * @note
+ * Details for I2C session registers. Please refer to NT3H2111_2211
+ * product data sheet section 8.3.12.
+ *
+ *****************************************************************************/
+sl_status_t nt3h2111_get_session(nt3h2111_session_reg_addr_t rega,
+ uint8_t *data);
+
+/**************************************************************************//**
+ * @brief
+ * Write to a session register in NT3H2111.
+ *
+ * @param[in] rega
+ * Register address within memory block
+ *
+ * @param[in] regd
+ * Register data to be written
+ *
+ * @returns
+ * Any error code
+ *
+ * @note
+ * Details for I2C session registers. Please refer to NT3H2111_2211
+ * product data sheet section 8.3.12.
+ *
+ *****************************************************************************/
+sl_status_t nt3h2111_set_session(nt3h2111_session_reg_addr_t rega,
+ uint8_t mask,
+ uint8_t regd);
+
+/**************************************************************************//**
+ * @brief
+ * Read a memory block (16 bytes) from NT3H2111.
+ *
+ * @param[in] mema
+ * The address of the block of memory (SRAM or EEPROM)
+ * that is intended to be read
+ *
+ * @param[out] data
+ * Data buffer to hold the result
+ *
+ * @returns
+ * I2C transfer status.
+ *
+ * @note
+ * Details for I2C READ operation, please refer to NT3H2111_2211 product
+ * data sheet section 9.7.
+ *****************************************************************************/
+sl_status_t nt3h2111_read_block(uint8_t mema, uint8_t *data);
+
+/**************************************************************************//**
+ * @brief
+ * Write a memory block (16 bytes) to NT3H2111.
+ *
+ * @param[in] mema
+ * The address of the block of memory (SRAM or EEPROM)
+ * that is intended to be written
+ *
+ * @param[in] data
+ * Data to be written
+ *
+ * @returns
+ * I2C transfer status.
+ *
+ * @note
+ * Details for I2C WRITE operation, please refer to NT3H2111_2211 product
+ * data sheet section 9.7.
+ *****************************************************************************/
+sl_status_t nt3h2111_write_block(uint8_t mema, const uint8_t *data);
+
+/***************************************************************************//**
+ * @brief Write byte(s) to the selected device
+ *
+ * This functions writes the specified number of bytes to the given address of
+ * the selected device. Writing to an invalid address is undefined.
+ *
+ * @param[in] addr
+ * The address of the byte of memory (SRAM or EEPROM)
+ * that is intended to be written
+ *
+ * @param[in] bytes
+ * Array of bytes to be written
+ *
+ * @param[in] len
+ * Number of bytes to be written
+ *
+ ******************************************************************************/
+sl_status_t nt3h2111_write_bytes(uint8_t addr,
+ const uint8_t *bytes,
+ uint16_t len);
+
+/***************************************************************************//**
+ * @brief Read byte(s) from the selected device
+ *
+ * This functions reads the specified number of bytes to the given address of
+ * the selected device. Reading from an invalid address
+ * will result in a failed read.
+ *
+ * @param[in] addr
+ * The address of the byte of memory (SRAM or EEPROM)
+ * that is intended to be read
+ *
+ * @param[in] bytes
+ * Array of bytes to store read data
+ *
+ * @param[in] len
+ * Number of bytes to be read
+ *
+ ******************************************************************************/
+sl_status_t nt3h2111_read_bytes(uint8_t addr, uint8_t *bytes, uint16_t len);
+
+/**************************************************************************//**
+ * @brief
+ * Encode NC_REG content to one byte of data.
+ *
+ * @param[in] nc_reg
+ * Content of NC_REG to be encoded
+ *
+ * @returns
+ * Encoded data
+ *
+ * @note
+ * Details for NC_REG. Please refer to NT3H2111_2211 product data sheet
+ * section 8.3.12.
+ *
+ * @warning
+ * This function is provided as prototype and has not been tested.
+ *****************************************************************************/
+uint8_t nt3h2111_encode_nc_reg(nt3h2111_nc_reg_t nc_reg);
+
+/**************************************************************************//**
+ * @brief
+ * Decode NC_REG content from one byte of raw data.
+ *
+ * @param[in] nc_reg
+ * One byte of raw NC_REG data to be decoded
+ *
+ * @returns
+ * Decoded NC_REG data
+ *
+ * @note
+ * Details for NC_REG. Please refer to NT3H2111_2211 product data sheet
+ * section 8.3.12.
+ *
+ * @warning
+ * This function is provided as prototype and has not been tested.
+ *****************************************************************************/
+nt3h2111_nc_reg_t nt3h2111_decode_nc_reg(uint8_t reg_value);
+
+/**************************************************************************//**
+ * @brief
+ * Encode I2C_CLOCK_STR content to one byte of data.
+ *
+ * @param[in] i2c_clock_str_reg
+ * Content of I2C_CLOCK_STR to be encoded
+ *
+ * @returns
+ * Encoded data
+ *
+ * @note
+ * Details for I2C_CLOCK_STR. Please refer to NT3H2111_2211 product data sheet
+ * section 8.3.12.
+ *
+ * @warning
+ * This function is provided as prototype and has not been tested.
+ *****************************************************************************/
+uint8_t nt3h2111_i2c_encode_clock_str(
+ nt3h2111_i2c_clock_str_t i2c_clock_str_reg);
+
+/***************************************************************************//**
+ * @brief
+ * Decode one byte of raw I2C_CLOCK_STR data.
+ *
+ * @param[in] i2c_clock_str_reg
+ * Raw I2C_CLOCK_STR data to be decoded
+ *
+ * @returns
+ * Decoded I2C_CLOCK_STR data
+ *
+ * @note
+ * Details for I2C_CLOCK_STR. Please refer to NT3H2111_2211 product data sheet
+ * section 8.3.12.
+ *
+ * @warning
+ * This function is provided as prototype and has not been tested.
+ ******************************************************************************/
+nt3h2111_i2c_clock_str_t nt3h2111_i2c_decode_clock_str(uint8_t reg_value);
+
+/***************************************************************************//**
+ * @brief
+ * Decode one byte of raw REG_LOCK data.
+ *
+ * @param[in] i2c_clock_str_reg
+ * Raw REG_LOCK data to be decoded
+ *
+ * @returns
+ * Decoded REG_LOCK data
+ *
+ * @note
+ * Details for REG_LOCK. Please refer to NT3H2111_2211 product data sheet
+ * section 8.3.12.
+ *
+ ******************************************************************************/
+nt3h2111_reg_lock_t nt3h2111_decode_reg_lock(uint8_t reg_value);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} (end addtogroup NT3H2111 Driver) */
+#endif // _MIKROE_NT3H2111_H_
diff --git a/driver/public/silabs/nfctag2_nt3h2111/inc/mikroe_nt3h2111_i2c.h b/driver/public/silabs/nfctag2_nt3h2111/inc/mikroe_nt3h2111_i2c.h
new file mode 100644
index 00000000..8fdc1797
--- /dev/null
+++ b/driver/public/silabs/nfctag2_nt3h2111/inc/mikroe_nt3h2111_i2c.h
@@ -0,0 +1,105 @@
+/***************************************************************************//**
+* @file mikroe_nt3h2111_i2c.h
+* @brief Types for I2C interface for NT3H2111.
+********************************************************************************
+* # License
+* Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+********************************************************************************
+*
+* SPDX-License-Identifier: Zlib
+*
+* The licensor of this software is Silicon Laboratories Inc.
+*
+* This software is provided \'as-is\', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*
+********************************************************************************
+* # Evaluation Quality
+* This code has been minimally tested to ensure that it builds and is suitable
+* as a demonstration for evaluation purposes only. This code will be maintained
+* at the sole discretion of Silicon Labs.
+*******************************************************************************/
+
+#ifndef _MIKROE_NT3H2111_I2C_H_
+#define _MIKROE_NT3H2111_I2C_H_
+
+#include "sl_status.h"
+#include "sl_i2cspm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @addtogroup NT3H2111 Driver
+ * @brief NT3H2111 I2C Types.
+ * @{
+ ******************************************************************************/
+
+/**************************************************************************//**
+ * @brief
+ * Read data through I2C.
+ *
+ * @param[in] i2c_handle
+ * The I2C instance to use
+ *
+ * @param[in] i2c_addr
+ * The I2C address to probe.
+ *
+ * @param[in] size
+ * Number of bytes to be read
+ *
+ * @param[out] pdata
+ * Buffer to store read data
+ *
+ * @returns
+ * I2C transfer result code.
+ *****************************************************************************/
+sl_status_t nt3h2111_i2c_read_bytes(sl_i2cspm_t *i2c_handle,
+ uint8_t i2c_addr,
+ uint32_t size,
+ uint8_t *pdata);
+
+/**************************************************************************//**
+ * @brief
+ * Write data through I2C.
+ *
+ * @param[in] i2c_handle
+ * The I2C instance to use
+ *
+ * @param[in] i2c_addr
+ * The I2C address to probe.
+ *
+ * @param[in] size
+ * Number of bytes to be written
+ *
+ * @param[out] pdata
+ * Buffer of data to be written
+ *
+ * @returns
+ * I2C transfer result code.
+ *****************************************************************************/
+sl_status_t nt3h2111_i2c_write_bytes(sl_i2cspm_t *i2c_handle,
+ uint8_t i2c_addr,
+ uint32_t size,
+ uint8_t *pdata);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} (end addtogroup NT3H2111 I2C Driver) */
+#endif
diff --git a/driver/public/silabs/nfctag2_nt3h2111/src/mikroe_nt3h2111.c b/driver/public/silabs/nfctag2_nt3h2111/src/mikroe_nt3h2111.c
new file mode 100644
index 00000000..e063a8b1
--- /dev/null
+++ b/driver/public/silabs/nfctag2_nt3h2111/src/mikroe_nt3h2111.c
@@ -0,0 +1,549 @@
+/***************************************************************************//**
+ * @file mikroe_nt3h2111.c
+ * @brief Implementation for high level NT3H2111 functionalities.
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+
+#include
+#include "em_gpio.h"
+#include "sl_sleeptimer.h"
+#include "mikroe_nt3h2111.h"
+
+#if !defined (min)
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+// Global variables
+static sl_i2cspm_t *nt3h2111_i2cspm_instance = NULL;
+static bool nt3h2111_is_initialized = false;
+
+/**************************************************************************//**
+ * @brief
+ * Initialize NT3H2111 peripherals.
+ *
+ * @param[in] init
+ * Initialization settings.
+ *****************************************************************************/
+sl_status_t nt3h2111_init(sl_i2cspm_t *i2cspm)
+{
+ if (i2cspm == NULL) {
+ return SL_STATUS_NULL_POINTER;
+ }
+
+ // If already initialized, return status
+ if (nt3h2111_is_initialized == true) {
+ return SL_STATUS_ALREADY_INITIALIZED;
+ }
+
+ // Update i2cspm instance and i2c addr
+ nt3h2111_i2cspm_instance = i2cspm;
+
+#if defined(MIKROE_NT3H211_FD_PORT) && defined(MIKROE_NT3H211_FD_PIN)
+ GPIO_PinModeSet(MIKROE_NT3H211_FD_PORT,
+ MIKROE_NT3H211_FD_PIN,
+ gpioModeInputPullFilter,
+ 1);
+#endif
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * De-initialize the NT3H2111.
+ ******************************************************************************/
+sl_status_t nt3h2111_deinit(void)
+{
+ if (nt3h2111_i2cspm_instance == false) {
+ return SL_STATUS_NOT_INITIALIZED;
+ }
+
+ // De-initialization tasks
+#if defined(MIKROE_NT3H211_FD_PORT) && defined(MIKROE_NT3H211_FD_PIN)
+ GPIO_PinModeSet(MIKROE_NT3H211_FD_PORT,
+ MIKROE_NT3H211_FD_PIN,
+ gpioModeDisabled,
+ 1);
+#endif
+ // Mark driver as not initialized
+ nt3h2111_i2cspm_instance = false;
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * Read a configuration register in NT3H2111.
+ ******************************************************************************/
+sl_status_t nt3h2111_get_config(nt3h2111_config_reg_addr_t rega, uint8_t *data)
+{
+ sl_status_t result;
+ uint8_t buff[2];
+
+ if (NULL == data) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Assign mema. */
+ buff[0] = NT3H2111_CONFIG_REG_ADDR;
+
+ /* Assign rega. */
+ buff[1] = rega;
+
+ /* Write addresses. */
+ result = nt3h2111_i2c_write_bytes(nt3h2111_i2cspm_instance,
+ MIKROE_NT3H211_ADDR,
+ 2,
+ buff);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+
+ /* Read regdat from NT3H2111. */
+ return nt3h2111_i2c_read_bytes(nt3h2111_i2cspm_instance,
+ MIKROE_NT3H211_ADDR,
+ 1,
+ data);
+}
+
+/***************************************************************************//**
+ * Write to a configuration register in NT3H2111.
+ ******************************************************************************/
+sl_status_t nt3h2111_set_config(nt3h2111_config_reg_addr_t rega,
+ uint8_t mask,
+ uint8_t regd)
+{
+ uint8_t buff[4];
+
+ /* Assign mema. */
+ buff[0] = NT3H2111_CONFIG_REG_ADDR;
+
+ /* Assign rega. */
+ buff[1] = rega;
+
+ /* Assign mask. */
+ buff[2] = mask;
+
+ /* Assign regdat. */
+ buff[3] = regd;
+
+ /* Write to NT3H2111. */
+ return nt3h2111_i2c_write_bytes(nt3h2111_i2cspm_instance,
+ MIKROE_NT3H211_ADDR,
+ 4,
+ buff);
+}
+
+/***************************************************************************//**
+ * Read a session register in NT3H2111.
+ ******************************************************************************/
+sl_status_t nt3h2111_get_session(nt3h2111_session_reg_addr_t rega,
+ uint8_t *data)
+{
+ sl_status_t result;
+ uint8_t buff[2];
+
+ if (NULL == data) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Assign mema. */
+ buff[0] = NT3H2111_SESSION_REG_ADDR;
+
+ /* Assign rega. */
+ buff[1] = rega;
+
+ /* Write addresses. */
+ result = nt3h2111_i2c_write_bytes(nt3h2111_i2cspm_instance,
+ MIKROE_NT3H211_ADDR,
+ 2,
+ buff);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+
+ /* Read regdat from NT3H2111. */
+ return nt3h2111_i2c_read_bytes(nt3h2111_i2cspm_instance,
+ MIKROE_NT3H211_ADDR,
+ 1,
+ data);
+}
+
+/***************************************************************************//**
+ * Write to a session register in NT3H2111.
+ ******************************************************************************/
+sl_status_t nt3h2111_set_session(nt3h2111_session_reg_addr_t rega,
+ uint8_t mask,
+ uint8_t regd)
+{
+ uint8_t buff[4];
+
+ /* Assign mema. */
+ buff[0] = NT3H2111_SESSION_REG_ADDR;
+
+ /* Assign rega. */
+ buff[1] = rega;
+
+ /* Assign mask. */
+ buff[2] = mask;
+
+ /* Assign regdat. */
+ buff[3] = regd;
+
+ /* Write to NT3H2111. */
+ return nt3h2111_i2c_write_bytes(nt3h2111_i2cspm_instance,
+ MIKROE_NT3H211_ADDR,
+ 4,
+ buff);
+}
+
+/***************************************************************************//**
+ * Read a memory block (16 bytes) from NT3H2111.
+ ******************************************************************************/
+sl_status_t nt3h2111_read_block(uint8_t mema, uint8_t *data)
+{
+ sl_status_t result;
+
+ if (NULL == data) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Write memory address of the block of memory that is intended to be read */
+ result = nt3h2111_i2c_write_bytes(nt3h2111_i2cspm_instance,
+ MIKROE_NT3H211_ADDR,
+ 1,
+ &mema);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+
+ /* Read a block. */
+ return nt3h2111_i2c_read_bytes(nt3h2111_i2cspm_instance,
+ MIKROE_NT3H211_ADDR,
+ NT3H2111_BLOCK_SIZE,
+ data);
+}
+
+/***************************************************************************//**
+ * Write a memory block (16 bytes) to NT3H2111.
+ ******************************************************************************/
+sl_status_t nt3h2111_write_block(uint8_t mema, const uint8_t *data)
+{
+ sl_status_t result = SL_STATUS_OK;
+ uint32_t timeout = NT3H2111_WRITE_DELAY_MS / 5 + 1;
+ uint8_t ns_reg;
+ uint8_t buff[NT3H2111_BLOCK_SIZE + 1];
+
+ if (NULL == data) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Assign mema. */
+ buff[0] = mema;
+
+ /* Assign data. */
+ memcpy(&buff[1], data, NT3H2111_BLOCK_SIZE);
+
+ /* Write to NT3H2111. */
+ result = nt3h2111_i2c_write_bytes(nt3h2111_i2cspm_instance,
+ MIKROE_NT3H211_ADDR,
+ sizeof(buff),
+ buff);
+ if (result != SL_STATUS_OK) {
+ return result;
+ }
+
+ /* Do not wait for completion when writing SRAM */
+ if ((mema >= NT3H2111_MEM_BLOCK_START_SRAM)
+ && (mema < NT3H2111_MEM_BLOCK_START_SRAM + NT3H2111_MEM_SRAM_BLOCKS)) {
+ return SL_STATUS_OK;
+ }
+
+ /* Wait for completion */
+ do {
+ sl_sleeptimer_delay_millisecond(5);
+ result = nt3h2111_get_session(SESSION_NS_REG, &ns_reg);
+ if (result != SL_STATUS_OK) {
+ break;
+ }
+
+ timeout--;
+ } while (timeout && (ns_reg & NT3H2111_NS_REG_MASK_EEPROM_WR_BUSY));
+
+ if (0 == timeout) {
+ return SL_STATUS_TIMEOUT;
+ }
+
+ return result;
+}
+
+/***************************************************************************//**
+ * Read byte(s) from the selected device
+ ******************************************************************************/
+sl_status_t nt3h2111_read_bytes(uint8_t addr, uint8_t *bytes, uint16_t len)
+{
+ sl_status_t result = SL_STATUS_OK;
+ uint8_t rx_buff[16];
+ uint16_t bytes_read = 0;
+
+ if (NULL == bytes) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ while (bytes_read < len) {
+ uint8_t current_block = (addr + bytes_read) / NT3H2111_BLOCK_SIZE;
+ uint8_t begin = (addr + bytes_read) % NT3H2111_BLOCK_SIZE;
+ uint8_t current_len =
+ min((len - bytes_read), (NT3H2111_BLOCK_SIZE - begin));
+
+ if (current_len < NT3H2111_BLOCK_SIZE) {
+ size_t i = 0;
+
+ /* Read block into rx_buff only */
+ result = nt3h2111_read_block(current_block, rx_buff);
+ if (result != SL_STATUS_OK) {
+ break;
+ }
+
+ /* Modify rx_buff */
+ for (i = 0; i < current_len; i++) {
+ bytes[bytes_read + i] = rx_buff[begin + i];
+ }
+ } else {
+ /* Full block read */
+ result = nt3h2111_read_block(current_block, bytes + bytes_read);
+ if (result != SL_STATUS_OK) {
+ break;
+ }
+ }
+
+ bytes_read += current_len;
+ }
+ return result;
+}
+
+/***************************************************************************//**
+ * Write byte(s) to the selected device
+ ******************************************************************************/
+sl_status_t nt3h2111_write_bytes(uint8_t addr,
+ const uint8_t *bytes,
+ uint16_t len)
+{
+ sl_status_t result = SL_STATUS_OK;
+ uint8_t rx_buff[16];
+ uint16_t bytes_written = 0;
+
+ if (NULL == bytes) {
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ while (bytes_written < len) {
+ uint8_t current_block = (addr + bytes_written) / NT3H2111_BLOCK_SIZE;
+ uint8_t begin = (addr + bytes_written) % NT3H2111_BLOCK_SIZE;
+ uint8_t current_len = min(len - bytes_written, NT3H2111_BLOCK_SIZE - begin);
+
+ if (current_len < NT3H2111_BLOCK_SIZE) {
+ size_t i = 0;
+
+ /* Read block into rx_buff only */
+ result = nt3h2111_read_block(current_block, rx_buff);
+ if (result != SL_STATUS_OK) {
+ break;
+ }
+
+ /* check if it is the first Block(0x00) and not the I2C Addr
+ * be careful with writing of first byte in management block
+ * the byte contains part of the serial number on read but
+ * on write the I2C address of the device can be modified
+ */
+ if ((0x00 == current_block) && (NT3H2111__MEM_ADRR_I2C_ADDR < begin)) {
+ rx_buff[0] = MIKROE_NT3H211_ADDR;
+ }
+
+ /* modify rx_buffer */
+ for (i = 0; i < current_len; i++) {
+ rx_buff[begin + i] = bytes[bytes_written + i];
+ }
+
+ /* Write back modified buffer */
+ result = nt3h2111_write_block(current_block, rx_buff);
+ if (result != SL_STATUS_OK) {
+ break;
+ }
+ } else {
+ /* Full block write */
+ result = nt3h2111_write_block(current_block,
+ (bytes + bytes_written));
+ if (result != SL_STATUS_OK) {
+ break;
+ }
+ }
+
+ bytes_written += current_len;
+ }
+
+ return result;
+}
+
+/***************************************************************************//**
+ * Encode NC_REG content to one byte of data.
+ ******************************************************************************/
+uint8_t nt3h2111_encode_nc_reg(nt3h2111_nc_reg_t nc_reg)
+{
+ uint8_t result = 0;
+
+ if (nc_reg.nfcs_i2c_rst_on_off) {
+ result += ((ON << NT3H2111_NC_REG_NFCS_I2C_RST_ON_OFF_SHIFT)
+ & NT3H2111_NC_REG_NFCS_I2C_RST_ON_OFF_M);
+ }
+
+ if (nc_reg.pthru_on_off) {
+ result += ((ON << NT3H2111_NC_REG_PTHRU_ON_OFF_SHIFT)
+ & NT3H2111_NC_REG_PTHRU_ON_OFF_M);
+ }
+
+ result += ((nc_reg.fd_off << NT3H2111_NC_REG_FD_OFF_SHIFT)
+ & NT3H2111_NC_REG_FD_OFF_M);
+
+ result += ((nc_reg.fd_on << NT3H2111_NC_REG_FD_ON_SHIFT)
+ & NT3H2111_NC_REG_FD_ON_M);
+
+ if (nc_reg.sram_mirror_on_off) {
+ result += ((ON << NT3H2111_NC_REG_SRAM_MIRROR_ON_OFF_SHIFT)
+ & NT3H2111_NC_REG_SRAM_MIRROR_ON_OFF_M);
+ }
+
+ if (nc_reg.transfer_dir) {
+ result += ((TRANSFER_DIR_NFC_TO_I2C << NT3H2111_NC_REG_TRANSFER_DIR_SHIFT)
+ & NT3H2111_NC_REG_TRANSFER_DIR_M);
+ }
+
+ return result;
+}
+
+/***************************************************************************//**
+ * Decode NC_REG content from one byte of raw data.
+ ******************************************************************************/
+nt3h2111_nc_reg_t nt3h2111_decode_nc_reg(uint8_t reg_value)
+{
+ nt3h2111_nc_reg_t nc_reg;
+
+ if (reg_value & BIT7_MASK) {
+ nc_reg.nfcs_i2c_rst_on_off = ON;
+ } else {
+ nc_reg.nfcs_i2c_rst_on_off = OFF;
+ }
+
+ if (reg_value & BIT6_MASK) {
+ nc_reg.pthru_on_off = ON;
+ } else {
+ nc_reg.pthru_on_off = OFF;
+ }
+
+ nc_reg.fd_off
+ = (reg_value & NT3H2111_NC_REG_FD_OFF_M >> NT3H2111_NC_REG_FD_OFF_SHIFT);
+
+ nc_reg.fd_on
+ = (reg_value & NT3H2111_NC_REG_FD_ON_M >> NT3H2111_NC_REG_FD_ON_SHIFT);
+
+ if (reg_value & BIT1_MASK) {
+ nc_reg.sram_mirror_on_off = ON;
+ } else {
+ nc_reg.sram_mirror_on_off = OFF;
+ }
+
+ if (reg_value & BIT0_MASK) {
+ nc_reg.transfer_dir = TRANSFER_DIR_NFC_TO_I2C;
+ } else {
+ nc_reg.transfer_dir = TRANSFER_DIR_I2C_TO_NFC;
+ }
+
+ return nc_reg;
+}
+
+/***************************************************************************//**
+ * Encode I2C_CLOCK_STR content to one byte of data.
+ ******************************************************************************/
+uint8_t nt3h2111_i2c_encode_clock_str(
+ nt3h2111_i2c_clock_str_t i2c_clock_str_reg)
+{
+ uint8_t result = 0;
+
+ if (i2c_clock_str_reg.i2c_clock_str) {
+ result += ((ENABLED << NT3H2111_I2C_CLOCK_STR_SHIFT)
+ & NT3H2111_I2C_CLOCK_STR_M);
+ }
+
+ return result;
+}
+
+/***************************************************************************//**
+ * Decode one byte of raw I2C_CLOCK_STR data.
+ ******************************************************************************/
+nt3h2111_i2c_clock_str_t nt3h2111_i2c_decode_clock_str(uint8_t reg_value)
+{
+ nt3h2111_i2c_clock_str_t i2c_clock_str_reg;
+
+ if (reg_value & (BIT1_MASK)) {
+ i2c_clock_str_reg.nrg_auth_reached = true;
+ }
+
+ if (reg_value & BIT0_MASK) {
+ i2c_clock_str_reg.i2c_clock_str = ENABLED;
+ } else {
+ i2c_clock_str_reg.i2c_clock_str = DISABLED;
+ }
+
+ return i2c_clock_str_reg;
+}
+
+/***************************************************************************//**
+ * Decode one byte of raw REG_LOCK data.
+ ******************************************************************************/
+nt3h2111_reg_lock_t nt3h2111_decode_reg_lock(uint8_t reg_value)
+{
+ nt3h2111_reg_lock_t reg_lock;
+
+ if (reg_value & BIT1_MASK) {
+ reg_lock.reg_lock_i2c = NT3H2111_REG_LOCKED;
+ } else {
+ reg_lock.reg_lock_i2c = NT3H2111_REG_UNLOCKED;
+ }
+ if (reg_value & BIT0_MASK) {
+ reg_lock.reg_lock_nfc = NT3H2111_REG_LOCKED;
+ } else {
+ reg_lock.reg_lock_nfc = NT3H2111_REG_UNLOCKED;
+ }
+
+ return reg_lock;
+}
diff --git a/driver/public/silabs/nfctag2_nt3h2111/src/mikroe_nt3h2111_i2c.c b/driver/public/silabs/nfctag2_nt3h2111/src/mikroe_nt3h2111_i2c.c
new file mode 100644
index 00000000..e697ea51
--- /dev/null
+++ b/driver/public/silabs/nfctag2_nt3h2111/src/mikroe_nt3h2111_i2c.c
@@ -0,0 +1,121 @@
+/***************************************************************************//**
+* @file mikroe_nt3h2111_i2c.c
+* @brief Implementation for I2C interface for NT3H2111.
+********************************************************************************
+* # License
+* Copyright 2023 Silicon Laboratories Inc. www.silabs.com
+********************************************************************************
+*
+* SPDX-License-Identifier: Zlib
+*
+* The licensor of this software is Silicon Laboratories Inc.
+*
+* This software is provided \'as-is\', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*
+*******************************************************************************
+* # Evaluation Quality
+* This code has been minimally tested to ensure that it builds and is suitable
+* as a demonstration for evaluation purposes only. This code will be maintained
+* at the sole discretion of Silicon Labs.
+*******************************************************************************/
+
+#include
+#include "mikroe_nt3h2111_i2c.h"
+
+/**************************************************************************//**
+ * @brief
+ * Read data through I2C.
+ *
+ * @param[in] i2c_handle
+ * The I2C instance to use
+ *
+ * @param[in] i2c_addr
+ * The I2C address to probe.
+ *
+ * @param[in] size
+ * Number of bytes to be read
+ *
+ * @param[out] pdata
+ * Buffer to store read data
+ *
+ * @returns
+ * I2C transfer result code.
+ *****************************************************************************/
+sl_status_t nt3h2111_i2c_read_bytes(sl_i2cspm_t *i2c_handle,
+ uint8_t i2c_addr,
+ uint32_t size,
+ uint8_t *pdata)
+{
+ I2C_TransferSeq_TypeDef seq;
+ I2C_TransferReturn_TypeDef result;
+
+ seq.addr = i2c_addr;
+ seq.flags = I2C_FLAG_READ;
+
+ /* Select command to issue */
+ seq.buf[0].data = pdata;
+ seq.buf[0].len = size;
+
+ result = I2CSPM_Transfer(i2c_handle, &seq);
+ if (result != i2cTransferDone) {
+ return SL_STATUS_TRANSMIT;
+ }
+
+ return SL_STATUS_OK;
+}
+
+/**************************************************************************//**
+ * @brief
+ * Write data through I2C.
+ *
+ * @param[in] i2c_handle
+ * The I2C instance to use
+ *
+ * @param[in] i2c_addr
+ * The I2C address to probe.
+ *
+ * @param[in] size
+ * Number of bytes to be written
+ *
+ * @param[out] pdata
+ * Buffer of data to be written
+ *
+ * @returns
+ * I2C transfer result code.
+ *****************************************************************************/
+sl_status_t nt3h2111_i2c_write_bytes(sl_i2cspm_t *i2c_handle,
+ uint8_t i2c_addr,
+ uint32_t size,
+ uint8_t *pdata)
+{
+ I2C_TransferSeq_TypeDef seq;
+ I2C_TransferReturn_TypeDef result;
+
+ seq.addr = i2c_addr;
+ seq.flags = I2C_FLAG_WRITE;
+
+ /* Select command to issue */
+ seq.buf[0].data = pdata;
+ seq.buf[0].len = size;
+
+ result = I2CSPM_Transfer(i2c_handle, &seq);
+ if (result != i2cTransferDone) {
+ return SL_STATUS_TRANSMIT;
+ }
+
+ return SL_STATUS_OK;
+}
diff --git a/driver/public/silabs/pir_ira_s210st01/config/pir_ira_s210st01_config.h b/driver/public/silabs/pir_ira_s210st01/config/pir_ira_s210st01_config.h
new file mode 100644
index 00000000..4b48c5c6
--- /dev/null
+++ b/driver/public/silabs/pir_ira_s210st01/config/pir_ira_s210st01_config.h
@@ -0,0 +1,72 @@
+/***************************************************************************//**
+ * @file pir_ira_s210st01_config.h
+ * @brief Configuration file for Sparkfun dosimeter type5.
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ * # Evaluation Quality
+ * This code has been minimally tested to ensure that it builds and is suitable
+ * as a demonstration for evaluation purposes only. This code will be maintained
+ * at the sole discretion of Silicon Labs.
+ ******************************************************************************/
+
+#ifndef PIR_IRA_S210ST01_CONFIG_H_
+#define PIR_IRA_S210ST01_CONFIG_H_
+
+#include "em_gpio.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// <<< sl:start pin_tool >>>
+
+// PIR_IRA_S210ST01_ADC_P
+// $[GPIO_PIR_IRA_S210ST01_ADC_P]
+#define PIR_IRA_S210ST01_ADC_P_PORT gpioPortD
+#define PIR_IRA_S210ST01_ADC_P_PIN 8
+// [GPIO_PIR_IRA_S210ST01_ADC_P]$
+
+// PIR_IRA_S210ST01_ADC_N
+// $[GPIO_PIR_IRA_S210ST01_ADC_N]
+#define PIR_IRA_S210ST01_ADC_N_PORT gpioPortA
+#define PIR_IRA_S210ST01_ADC_N_PIN 6
+// [GPIO_PIR_IRA_S210ST01_ADC_N]$
+
+// PIR_IRA_S210ST01_LDO_SHDN_B
+// $[GPIO_PIR_IRA_S210ST01_LDO_SHDN_B]
+#define PIR_IRA_S210ST01_LDO_SHDN_B_PORT gpioPortC
+#define PIR_IRA_S210ST01_LDO_SHDN_B_PIN 9
+// [GPIO_PIR_IRA_S210ST01_LDO_SHDN_B]$
+
+// <<< sl:end pin_tool >>>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PIR_IRA_S210ST01_CONFIG_H_ */
diff --git a/driver/public/silabs/pir_ira_s210st01/inc/pir_ira_s210st01.h b/driver/public/silabs/pir_ira_s210st01/inc/pir_ira_s210st01.h
new file mode 100644
index 00000000..0fe595d8
--- /dev/null
+++ b/driver/public/silabs/pir_ira_s210st01/inc/pir_ira_s210st01.h
@@ -0,0 +1,224 @@
+/***************************************************************************//**
+ * @file
+ * @brief Driver for PIR sensor
+ * @version 1.0.2
+ *******************************************************************************
+ * # License
+ * Copyright 2020 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+
+#ifndef PIR_H
+#define PIR_H
+
+#include
+#include
+#include "sl_status.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @addtogroup PIR
+ * @{
+ *
+ * @brief
+ * The implementation of PIR sensor driver using the PIR sensor on the
+ * occupancy
+ * sensor EXP board.
+ *
+ * The target application of the PIR sensor would be smart lighting or alarm
+ * systems in home automation. Whenever certain motion of the human body is
+ * detected, the system will either turn on the light or the alarm.
+ ******************************************************************************/
+
+/// Configures whether to use the internal opamp or an external opamp.
+typedef enum {
+ pir_opamp_mode_internal = 0,
+ pir_opamp_mode_external = 1,
+} pir_opamp_mode_t;
+
+/// Selects whether to use the dedicated main opamp ports or use the APORT
+/// selection.
+typedef enum {
+ pir_opamp_main_ports = 0,
+ pir_opamp_aport = 1,
+} pir_opamp_port_t;
+
+/// Selects whether to operate the ADC in single ended positive, negative or
+/// differential mode.
+typedef enum {
+ pir_adc_source_pos = 0,
+ pir_adc_source_neg = 1,
+ pir_adc_source_diff = 2,
+} pir_adc_source_t;
+
+/***************************************************************************//**
+ * @brief
+ * ADC IRQ callback function
+ *
+ * @note
+ * This function is called whenever an ADC interrupt is received. It's up to
+ * the application to decide how to handle the interrupt. However, in order to
+ * detect motion properly, pir_detect_motion function must be called within
+ * 30ms after receiving the interrupt to process the latest ADC sample .
+ ******************************************************************************/
+typedef void (*pir_adc_irq_callback_t)();
+
+/***************************************************************************//**
+ * @brief
+ * Motion detection result callback function
+ *
+ * @param[in] motion_status
+ * True indicates motion on is detected
+ * False indicates motion off is detected
+ *
+ * @note
+ * This function is called whenever motion on/off status is detected in the
+ * algorithm. The application should check the motion_status and take actions
+ * accordingly.
+ ******************************************************************************/
+typedef void (*pir_motion_detection_callback_t)(bool motion_status);
+
+/// Structure for PIR sample.
+typedef struct {
+ int32_t timestamp_ms; ///< A 16-bit timestamp from the 1024 Hz counter.
+ int32_t adc_sample; ///< The ADC sample measuring the PIR voltage.
+ int32_t win_base; ///< The center of the detector window.
+ int32_t adc_upper_threshold; ///< The upper threshold of the detector window.
+ int32_t adc_lower_threshold; ///< The lower threshold of the detector window.
+ bool motion_status; ///< Whether motion was detected.
+} pir_sample_t;
+
+/// Initialization structure for PIR driver.
+typedef struct {
+ ///< Use internal or external opamp.
+ pir_opamp_mode_t opamp_mode;
+ ///< The duration of time(in seconds) motion on being asserted after detected.
+ uint32_t motion_on_time;
+ ///< The peak to peak window size for motion detection in lsb.
+ uint32_t win_size;
+ ///< ADC IRQ callback.
+ pir_adc_irq_callback_t adc_irq_callback;
+ ///< Motion detection result callback.
+ pir_motion_detection_callback_t motion_detection_callback;
+ ///< PIR sample queue size. Must be no smaller than 4.
+ uint16_t sample_queue_size;
+ ///< A sample buffer supplied by the user.
+ pir_sample_t *sample_queue;
+ ///< Whether to apply timestamp to PIR samples or not.
+ bool use_timestamp;
+} pir_init_t;
+
+/// Default initialization structure for PIR driver.
+#define PIR_INIT_DEFAULT \
+ { \
+ .opamp_mode = pir_opamp_mode_external, \
+ .motion_on_time = 4, \
+ .win_size = 1024, \
+ .adc_irq_callback = NULL, \
+ .motion_detection_callback = NULL, \
+ .sample_queue_size = 4, \
+ .sample_queue = NULL, \
+ .use_timestamp = true, \
+ }
+
+/***************************************************************************//**
+ * @brief
+ * Initializes peripherals for PIR
+ *
+ * @param[in] pir_init
+ * Pointer to PIR initialization structure
+ *
+ * @param[in] adc_enter_em2
+ * Sets up ADC to run in EM2 when set to true
+ *
+ * @return
+ * Returns zero on OK, non-zero otherwise
+ ******************************************************************************/
+sl_status_t pir_init(pir_init_t *pir_init, bool adc_enter_em2);
+
+/***************************************************************************//**
+ * @brief
+ * Runs the motion detection algorithm
+ *
+ * @note
+ * This algorithms takes roughly 150us and must run on the latest ADC sample
+ * after receiving the ADC interrupt.
+ *
+ * @return
+ * Returns zero on OK, non-zero otherwise
+ ******************************************************************************/
+sl_status_t pir_detect_motion(void);
+
+/***************************************************************************//**
+ * @brief
+ * Starts PIR sensor sampling
+ *
+ * @return
+ * Returns zero on OK, non-zero otherwise
+ ******************************************************************************/
+sl_status_t pir_start(void);
+
+/***************************************************************************//**
+ * @brief
+ * Stops PIR sensor sampling
+ *
+ * @return
+ * Returns zero on OK, non-zero otherwise
+ ******************************************************************************/
+sl_status_t pir_stop(void);
+
+/***************************************************************************//**
+ * @brief
+ * Reads out a sample from the PIR sample queue
+ *
+ * @param[out] pir_sample
+ * Pointer to the PIR sample
+ *
+ * @return
+ * Returns zero on OK, non-zero otherwise
+ ******************************************************************************/
+sl_status_t pir_read_queue(pir_sample_t *pir_sample);
+
+/***************************************************************************//**
+ * @brief
+ * Gets number of samples in the queue.
+ *
+ * @param[out] status
+ * Pointer to the status
+ *
+ * @return
+ * The number of samples in the queue.
+ ******************************************************************************/
+sl_status_t pir_get_queue_size(uint16_t *size);
+
+/** @} (end addtogroup PIR) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PIR_H
diff --git a/driver/public/silabs/pir_ira_s210st01/src/pir_ira_s210st01_s1.c b/driver/public/silabs/pir_ira_s210st01/src/pir_ira_s210st01_s1.c
new file mode 100644
index 00000000..d512ace3
--- /dev/null
+++ b/driver/public/silabs/pir_ira_s210st01/src/pir_ira_s210st01_s1.c
@@ -0,0 +1,838 @@
+/***************************************************************************//**
+ * @file
+ * @brief PIR driver.
+ * @version 1.0.2
+ *******************************************************************************
+ * # License
+ * Copyright 2019 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "em_cmu.h"
+#include "em_emu.h"
+#include "em_gpio.h"
+#include "em_prs.h"
+#include "em_cryotimer.h"
+#include "em_opamp.h"
+#include "em_adc.h"
+#include "em_vdac.h"
+#include "em_opamp.h"
+#include "em_letimer.h"
+
+#include
+#include
+#include
+#include
+
+#define ADC_PERIPHERAL ADC0
+#define ADC_PERIPHERAL_NO 0
+
+#define ADC_SAMPLE_QUEUE_SIZE 4 // Must be at least 4
+
+/// The adcSource variable should be set to adcSourceAdcDiff for PIR operation.
+/// The single ended modes are additional modes for signal chain analysis with a
+/// voltage source.
+#define PIR_SOURCE_POS 0
+#define PIR_SOURCE_NEG 1
+#define PIR_SOURCE_DIFF 2
+#if defined(PIR_IRA_S210ST01_ADC_P_PORT) && \
+ defined(PIR_IRA_S210ST01_ADC_P_PIN) && \
+ defined(PIR_IRA_S210ST01_ADC_N_PORT) && \
+ defined(PIR_IRA_S210ST01_ADC_N_PIN)
+#define PIR_SOURCE PIR_SOURCE_DIFF
+#elif defined(PIR_IRA_S210ST01_ADC_P_PORT) && \
+ defined(PIR_IRA_S210ST01_ADC_P_PIN)
+#define PIR_SOURCE PIR_SOURCE_POS
+#else
+#define PIR_SOURCE PIR_SOURCE_NEG
+#error "The posSel of the ADC is not defined for the kit, only the negSel"
+#endif
+
+/// PIR sample queue structure
+typedef struct {
+ volatile uint16_t head; ///< Index of next byte to get.
+ volatile uint16_t tail; ///< Index of where to enqueue next
+ ///< byte.
+ volatile uint16_t used; ///< Number of bytes queued.
+ uint16_t size; ///< Size of queue.
+ pir_sample_t *sample; ///< Pointer to PIR sample buffer.
+} sample_queue_t;
+
+static pir_init_t pir_instance; // An instance that holds the configuration
+static uint32_t lockout_counter = 0; // The time, in samples, remaining on the
+ // lockout window after detection.
+static int32_t win_base = 0; // The low frequency mean of the PIR input
+ // signal.
+
+static sample_queue_t app_queue; // Buffer PIR samples for application layer
+ // debugging.
+static sample_queue_t adc_queue; // Buffer ADC samples for motion detection
+ // algorithm.
+static pir_sample_t adc_sample_queue[ADC_SAMPLE_QUEUE_SIZE]; // ADC sample
+ // buffer.
+
+#if PIR_SOURCE == PIR_SOURCE_DIFF || PIR_SOURCE == PIR_SOURCE_POS
+static const ADC_PosSel_TypeDef adc_aportx_table_A[] = {
+ adcPosSelAPORT3XCH8,
+ adcPosSelAPORT4XCH9,
+ adcPosSelAPORT3XCH10,
+ adcPosSelAPORT4XCH11,
+ adcPosSelAPORT3XCH12,
+ adcPosSelAPORT4XCH13,
+ adcPosSelAPORT3XCH14,
+ adcPosSelAPORT4XCH15
+};
+static const ADC_PosSel_TypeDef adc_aportx_table_B[] = {
+ adcPosSelAPORT3XCH22,
+ adcPosSelAPORT4XCH23,
+ adcPosSelAPORT3XCH24,
+ adcPosSelAPORT4XCH25,
+ adcPosSelAPORT3XCH26,
+ adcPosSelAPORT4XCH27,
+ adcPosSelAPORT3XCH28,
+ adcPosSelAPORT4XCH29,
+ adcPosSelAPORT3XCH30,
+ adcPosSelAPORT4XCH31
+};
+static const ADC_PosSel_TypeDef adc_aportx_table_C[] = {
+ adcPosSelAPORT1XCH0,
+ adcPosSelAPORT2XCH1,
+ adcPosSelAPORT1XCH2,
+ adcPosSelAPORT2XCH3,
+ adcPosSelAPORT1XCH4,
+ adcPosSelAPORT2XCH5,
+ adcPosSelAPORT1XCH6,
+ adcPosSelAPORT2XCH7,
+ adcPosSelAPORT1XCH8,
+ adcPosSelAPORT2XCH9,
+ adcPosSelAPORT1XCH10,
+ adcPosSelAPORT2XCH11,
+};
+static const ADC_PosSel_TypeDef adc_aportx_table_D[] = {
+ adcPosSelAPORT3XCH0,
+ adcPosSelAPORT4XCH1,
+ adcPosSelAPORT3XCH2,
+ adcPosSelAPORT4XCH3,
+ adcPosSelAPORT3XCH4,
+ adcPosSelAPORT4XCH5,
+ adcPosSelAPORT3XCH6,
+ adcPosSelAPORT4XCH7,
+};
+static const ADC_PosSel_TypeDef adc_aportx_table_F[] = {
+ adcPosSelAPORT1XCH16,
+ adcPosSelAPORT2XCH17,
+ adcPosSelAPORT1XCH18,
+ adcPosSelAPORT2XCH19,
+ adcPosSelAPORT1XCH20,
+ adcPosSelAPORT2XCH21,
+ adcPosSelAPORT1XCH22,
+ adcPosSelAPORT2XCH23,
+ adcPosSelAPORT1XCH24,
+ adcPosSelAPORT2XCH25,
+ adcPosSelAPORT1XCH26,
+ adcPosSelAPORT2XCH27,
+ adcPosSelAPORT1XCH28,
+ adcPosSelAPORT2XCH29,
+ adcPosSelAPORT1XCH30,
+ adcPosSelAPORT2XCH31
+};
+static const ADC_PosSel_TypeDef adc_aportx_table_I[] = {
+ adcPosSelAPORT0XCH0,
+ adcPosSelAPORT0XCH1,
+ adcPosSelAPORT0XCH2,
+ adcPosSelAPORT0XCH3
+};
+#endif
+
+#if PIR_SOURCE == PIR_SOURCE_DIFF || PIR_SOURCE == PIR_SOURCE_NEG
+static const ADC_NegSel_TypeDef adc_aporty_table_A[] = {
+ adcNegSelAPORT4YCH8,
+ adcNegSelAPORT3YCH9,
+ adcNegSelAPORT4YCH10,
+ adcNegSelAPORT3YCH11,
+ adcNegSelAPORT4YCH12,
+ adcNegSelAPORT3YCH13,
+ adcNegSelAPORT4YCH14,
+ adcNegSelAPORT3YCH15
+};
+static const ADC_NegSel_TypeDef adc_aporty_table_B[] = {
+ adcNegSelAPORT4YCH22,
+ adcNegSelAPORT3YCH23,
+ adcNegSelAPORT4YCH24,
+ adcNegSelAPORT3YCH25,
+ adcNegSelAPORT4YCH26,
+ adcNegSelAPORT3YCH27,
+ adcNegSelAPORT4YCH28,
+ adcNegSelAPORT3YCH29,
+ adcNegSelAPORT4YCH30,
+ adcNegSelAPORT3YCH31
+};
+static const ADC_NegSel_TypeDef adc_aporty_table_C[] = {
+ adcNegSelAPORT2YCH0,
+ adcNegSelAPORT1YCH1,
+ adcNegSelAPORT2YCH2,
+ adcNegSelAPORT1YCH3,
+ adcNegSelAPORT2YCH4,
+ adcNegSelAPORT1YCH5,
+ adcNegSelAPORT2YCH6,
+ adcNegSelAPORT1YCH7,
+ adcNegSelAPORT2YCH8,
+ adcNegSelAPORT1YCH9,
+ adcNegSelAPORT2YCH10,
+ adcNegSelAPORT1YCH11,
+};
+static const ADC_NegSel_TypeDef adc_aporty_table_D[] = {
+ adcNegSelAPORT4YCH0,
+ adcNegSelAPORT3YCH1,
+ adcNegSelAPORT4YCH2,
+ adcNegSelAPORT3YCH3,
+ adcNegSelAPORT4YCH4,
+ adcNegSelAPORT3YCH5,
+ adcNegSelAPORT4YCH6,
+ adcNegSelAPORT3YCH7,
+};
+static const ADC_NegSel_TypeDef adc_aporty_table_F[] = {
+ adcNegSelAPORT2YCH16,
+ adcNegSelAPORT1YCH17,
+ adcNegSelAPORT2YCH18,
+ adcNegSelAPORT1YCH19,
+ adcNegSelAPORT2YCH20,
+ adcNegSelAPORT1YCH21,
+ adcNegSelAPORT2YCH22,
+ adcNegSelAPORT1YCH23,
+ adcNegSelAPORT2YCH24,
+ adcNegSelAPORT1YCH25,
+ adcNegSelAPORT2YCH26,
+ adcNegSelAPORT1YCH27,
+ adcNegSelAPORT2YCH28,
+ adcNegSelAPORT1YCH29,
+ adcNegSelAPORT2YCH30,
+ adcNegSelAPORT1YCH31
+};
+static const ADC_NegSel_TypeDef adc_aporty_table_I[] = {
+ adcNegSelAPORT0YCH0,
+ adcNegSelAPORT0YCH1,
+ adcNegSelAPORT0YCH2,
+ adcNegSelAPORT0YCH3
+};
+#endif
+
+#if PIR_SOURCE == PIR_SOURCE_DIFF || PIR_SOURCE == PIR_SOURCE_POS
+static ADC_PosSel_TypeDef get_adc_aportx(GPIO_Port_TypeDef port_index,
+ unsigned int pin_index)
+{
+ switch (port_index) {
+ case gpioPortA:
+ if (pin_index <= 7) {
+ return adc_aportx_table_A[pin_index];
+ } else {
+ return adcPosSelVSS;
+ }
+
+ case gpioPortB:
+ if ((pin_index >= 6) && (pin_index <= 15)) {
+ return adc_aportx_table_B[pin_index - 6];
+ } else {
+ return adcPosSelVSS;
+ }
+
+ case gpioPortC:
+ if (pin_index <= 11) {
+ return adc_aportx_table_C[pin_index];
+ } else {
+ return adcPosSelVSS;
+ }
+
+ case gpioPortD:
+ if ((pin_index >= 8) && (pin_index <= 15)) {
+ return adc_aportx_table_D[pin_index - 8];
+ } else {
+ return adcPosSelVSS;
+ }
+
+ case gpioPortF:
+ if (pin_index <= 15) {
+ return adc_aportx_table_F[pin_index];
+ } else {
+ return adcPosSelVSS;
+ }
+
+ case gpioPortI:
+ if (pin_index <= 3) {
+ return adc_aportx_table_I[pin_index];
+ } else {
+ return adcPosSelVSS;
+ }
+
+ default:
+ return adcPosSelVSS;
+ }
+ return adcPosSelVSS;
+}
+
+#endif
+
+#if PIR_SOURCE == PIR_SOURCE_DIFF || PIR_SOURCE == PIR_SOURCE_NEG
+static ADC_NegSel_TypeDef get_adc_aporty(GPIO_Port_TypeDef port_index,
+ unsigned int pin_index)
+{
+ switch (port_index) {
+ case gpioPortA:
+ if (pin_index <= 7) {
+ return adc_aporty_table_A[pin_index];
+ } else {
+ return adcNegSelVSS;
+ }
+
+ case gpioPortB:
+ if ((pin_index >= 6) && (pin_index <= 15)) {
+ return adc_aporty_table_B[pin_index - 6];
+ } else {
+ return adcNegSelVSS;
+ }
+
+ case gpioPortC:
+ if (pin_index <= 11) {
+ return adc_aporty_table_C[pin_index];
+ } else {
+ return adcNegSelVSS;
+ }
+
+ case gpioPortD:
+ if ((pin_index >= 8) && (pin_index <= 15)) {
+ return adc_aporty_table_D[pin_index - 8];
+ } else {
+ return adcNegSelVSS;
+ }
+
+ case gpioPortF:
+ if (pin_index <= 15) {
+ return adc_aporty_table_F[pin_index];
+ } else {
+ return adcNegSelVSS;
+ }
+
+ case gpioPortI:
+ if (pin_index <= 3) {
+ return adc_aporty_table_I[pin_index];
+ } else {
+ return adcNegSelVSS;
+ }
+
+ default:
+ return adcNegSelVSS;
+ }
+ return adcNegSelVSS;
+}
+
+#endif
+
+/***************************************************************************//**
+ * @brief
+ * Updates the ADC hardware thresholds for a motion event trigger.
+ *
+ * Inputs must mast the conversion data representation. For oversampled
+ * conversions, the resolution is 16-bit, regardless if the OVS setting
+ * does not achieve 16-bit resolution.
+ *
+ * @param[in] win_base
+ * The midpoint of the window. Thresholds are the base +/- 0.5*winSize
+ *
+ * @param[in] win_size
+ * The total peak to peak width of the window.
+ ******************************************************************************/
+static void update_adc_thresholds(int32_t win_base, uint32_t win_size)
+{
+ int32_t pos_thresh = win_base + win_size / 2;
+ int32_t neg_thresh = win_base - win_size / 2;
+
+ // Ensure thresholds are within int16_t for ADC window comparator.
+ int32_t pos_thresh_max, neg_thresh_min;
+#if PIR_SOURCE == PIR_SOURCE_DIFF
+ pos_thresh_max = 32767;
+ neg_thresh_min = -32768;
+#else
+ pos_thresh_max = 65535;
+ neg_thresh_min = 0;
+#endif
+
+ if (pos_thresh > pos_thresh_max) {
+ pos_thresh = pos_thresh_max;
+ }
+ if (neg_thresh < neg_thresh_min) {
+ neg_thresh = neg_thresh_min;
+ }
+
+ ADC0->CMPTHR =
+ ((pos_thresh << _ADC_CMPTHR_ADGT_SHIFT) & _ADC_CMPTHR_ADGT_MASK)
+ | ((neg_thresh <<
+ _ADC_CMPTHR_ADLT_SHIFT) & _ADC_CMPTHR_ADLT_MASK);
+}
+
+/***************************************************************************//**
+ * @brief
+ * Initializes the non inverting amplifier for PIR signal chain.
+ ******************************************************************************/
+static void init_opamp(void)
+{
+ CMU_ClockEnable(cmuClock_VDAC0, true);
+
+ // Errata VDAC_E201 for PG/JG/MG/BG12 causes contention if APORT is used for
+ // output.
+ // Use of dedicated opamp output pin or careful mapping of APORT buses is
+ // recommended.
+ OPAMP_Init_TypeDef opaInit = OPA_INIT_NON_INVERTING;
+ opaInit.resInMux = opaResInMuxDisable;
+ opaInit.resSel = opaResSelDefault;
+
+ opaInit.posSel = opaPosSelPosPad;
+ opaInit.negSel = opaNegSelNegPad;
+ opaInit.outMode = opaOutModeDisable;
+ opaInit.outPen = VDAC_OPA_OUT_MAINOUTEN;
+
+ const uint32_t opampCh = 1;
+ OPAMP_Enable(VDAC0, OPA1, &opaInit);
+
+ // Set INCBW for 2.5x increase in GBW, only stable for G > 3.
+ VDAC0->OPA[opampCh].CTRL |= VDAC_OPA_CTRL_INCBW;
+
+ // Set DRIVESTRENGTH=0 to minimize current.
+ VDAC0->OPA[opampCh].CTRL &= ~_VDAC_OPA_CTRL_DRIVESTRENGTH_MASK;
+ VDAC0->OPA[opampCh].CTRL |= (0 << _VDAC_OPA_CTRL_DRIVESTRENGTH_SHIFT);
+}
+
+/***************************************************************************//**
+ * @brief
+ * Initializes the ADC, CRYOTIMER and PRS for PIR operation.
+ *
+ * @details
+ * PRS triggering of the ADC in EM2 is only possible on > Series 1 MCUs.
+ *
+ * @param[in] adc_enter_em2
+ * Sets up ADC to run in EM2 when set to true.
+ ******************************************************************************/
+static sl_status_t init_adc(bool adc_enter_em2)
+{
+ // Initialize the ADC.
+ CMU_ClockEnable(cmuClock_ADC0, true);
+
+ ADC_Init_TypeDef adcInit = ADC_INIT_DEFAULT;
+ adcInit.ovsRateSel = adcOvsRateSel2;
+
+ if (adc_enter_em2) {
+ CMU_AUXHFRCOBandSet(cmuAUXHFRCOFreq_4M0Hz);
+ CMU->ADCCTRL = CMU_ADCCTRL_ADC0CLKSEL_AUXHFRCO;
+ adcInit.em2ClockConfig = adcEm2ClockOnDemand;
+ adcInit.prescale = ADC_PrescaleCalc(cmuAUXHFRCOFreq_4M0Hz,
+ CMU_AUXHFRCOBandGet());
+ adcInit.timebase = ADC_TimebaseCalc(CMU_AUXHFRCOBandGet());
+ } else {
+ adcInit.timebase = ADC_TimebaseCalc(0);
+ }
+
+ ADC_InitSingle_TypeDef adcInitSingle = ADC_INITSINGLE_DEFAULT;
+ adcInitSingle.resolution = adcResOVS;
+ adcInitSingle.reference = adcRef1V25;
+ adcInitSingle.prsEnable = true;
+ adcInitSingle.prsSel = adcPRSSELCh0;
+ adcInitSingle.leftAdjust = true;
+ adcInitSingle.acqTime = adcAcqTime64;
+
+#if PIR_SOURCE == PIR_SOURCE_POS
+ adcInitSingle.posSel = get_adc_aportx(PIR_IRA_S210ST01_ADC_P_PORT,
+ PIR_IRA_S210ST01_ADC_P_PIN);
+ adcInitSingle.negSel = adcNegSelVSS;
+ if (adcInitSingle.posSel == adcPosSelVSS) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+ adcInitSingle.diff = false;
+#elif PIR_SOURCE == PIR_SOURCE_NEG
+ // The posSel of the ADC_N is not defined for the kit, only the negSel.
+ adcInitSingle.posSel = adcPosSelAVDD;
+ adcInitSingle.negSel = get_adc_aporty(PIR_IRA_S210ST01_ADC_N_PORT,
+ PIR_IRA_S210ST01_ADC_N_PIN);
+ if (adcInitSingle.negSel == adcNegSelVSS) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+ adcInitSingle.diff = false;
+#elif PIR_SOURCE == PIR_SOURCE_DIFF
+ adcInitSingle.posSel = get_adc_aportx(PIR_IRA_S210ST01_ADC_P_PORT,
+ PIR_IRA_S210ST01_ADC_P_PIN);
+ adcInitSingle.negSel = get_adc_aporty(PIR_IRA_S210ST01_ADC_N_PORT,
+ PIR_IRA_S210ST01_ADC_N_PIN);
+ if ((adcInitSingle.posSel == adcPosSelVSS)
+ || (adcInitSingle.negSel == adcNegSelVSS)) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+ adcInitSingle.diff = true;
+#endif
+
+ ADC_Init(ADC0, &adcInit);
+ ADC_InitSingle(ADC0, &adcInitSingle);
+
+ // Set ADC FIFO level to max to minimize EM0 wakeups when the ADC sample
+ // remains within window.
+ static const uint32_t dataValidLevel = 3; // ADC SINGLE IRQ is when DVL+1
+ // single channels are available
+ // in the FIFO.
+ ADC0->SINGLECTRLX &= ~_ADC_SINGLECTRLX_DVL_MASK;
+ ADC0->SINGLECTRLX |= (dataValidLevel << _ADC_SINGLECTRLX_DVL_SHIFT);
+
+ update_adc_thresholds(win_base, pir_instance.win_size);
+//
+// // Initialize the CRYOTIMER.
+// CMU_OscillatorEnable(cmuOsc_ULFRCO, true, true);
+ CMU_ClockEnable(cmuClock_CRYOTIMER, true);
+
+ // Run CRYOTIMER on ULFRCO (1024 Hz) and trigger ADC to set the sampling
+ // period.
+ CRYOTIMER_Init_TypeDef cryoInit = CRYOTIMER_INIT_DEFAULT;
+ cryoInit.osc = cryotimerOscULFRCO;
+ cryoInit.presc = cryotimerPresc_1;
+ cryoInit.period = cryotimerPeriod_8; // Sampling frequency is 1024 / 32 = 32
+ // Hz.
+ CRYOTIMER_Init(&cryoInit);
+
+ // PRS is the triggering connection between CRYOTIMER and ADC.
+ CMU_ClockEnable(cmuClock_PRS, true);
+ PRS_SourceAsyncSignalSet(0,
+ PRS_CH_CTRL_SOURCESEL_CRYOTIMER,
+ PRS_CH_CTRL_SIGSEL_CRYOTIMERPERIOD);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Initialize GPIO.
+ ******************************************************************************/
+static void init_gpio(void)
+{
+ CMU_ClockEnable(cmuClock_GPIO, true);
+ GPIO_PinModeSet(PIR_IRA_S210ST01_LDO_SHDN_B_PORT,
+ PIR_IRA_S210ST01_LDO_SHDN_B_PIN,
+ gpioModePushPull,
+ 0);
+#if defined(PIR_IRA_S210ST01_ADC_P_PORT) && defined(PIR_IRA_S210ST01_ADC_P_PIN)
+ // ADC_P
+ GPIO_PinModeSet(PIR_IRA_S210ST01_ADC_P_PORT,
+ PIR_IRA_S210ST01_ADC_P_PIN,
+ gpioModeDisabled,
+ 0);
+#endif
+#if defined(PIR_IRA_S210ST01_ADC_N_PORT) && defined(PIR_IRA_S210ST01_ADC_N_PIN)
+ // ADC_N
+ GPIO_PinModeSet(PIR_IRA_S210ST01_ADC_N_PORT,
+ PIR_IRA_S210ST01_ADC_N_PIN,
+ gpioModeDisabled,
+ 0);
+#endif
+}
+
+/***************************************************************************//**
+ * @brief
+ * Initialize timers for time stamping samples to the GUI.
+ *
+ * @details
+ * LETIMER0 will operate at 1024 Hz time stamp clock.
+ ******************************************************************************/
+static void init_timestamp_clock(void)
+{
+ // LETIMER Initialization
+ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
+ CMU_ClockEnable(cmuClock_HFLE, true);
+ CMU_ClockEnable(cmuClock_LETIMER0, true);
+ CMU_ClockDivSet(cmuClock_LETIMER0, cmuClkDiv_32); // 32,768 Hz / 32 = 1024 Hz
+ // = 976.5625 us period
+
+ LETIMER_Init_TypeDef letimerInit = LETIMER_INIT_DEFAULT;
+ LETIMER_Init(LETIMER0, &letimerInit);
+}
+
+/***************************************************************************//**
+ * @brief
+ * Enqueue the PIR sample.
+ ******************************************************************************/
+static void enqueue_sample(sample_queue_t *queue, pir_sample_t sample)
+{
+ queue->sample[queue->head] = sample;
+ queue->head++;
+ if (queue->head == queue->size) {
+ queue->head = 0;
+ }
+ queue->used++;
+
+ if (queue->head == queue->tail) {
+ // If buffer is full, drop the oldest sample in the circular buffer and
+ // update the tail pointer.
+ queue->tail++;
+ if (queue->tail == queue->size) {
+ queue->tail = 0;
+ }
+ queue->used = queue->size;
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Dequeue the PIR sample.
+ ******************************************************************************/
+static void dequeue_sample(sample_queue_t *queue, pir_sample_t *sample)
+{
+ if (queue->used < 1) {
+ sample = NULL;
+ }
+
+ *sample = queue->sample[queue->tail];
+ queue->tail++;
+ if (queue->tail == queue->size) {
+ queue->tail = 0;
+ }
+ queue->used -= 1;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Initializes peripherals for PIR
+ *
+ * @param[in] pir_init
+ * A pointer to PIR initialization structure
+ *
+ * @param[in] adc_enter_em2
+ * Sets up ADC to run in EM2 when set to true
+ ******************************************************************************/
+sl_status_t pir_init(pir_init_t *pir_init, bool adc_enter_em2)
+{
+ init_gpio();
+ // Enable LDO to startup VPIR.
+ GPIO_PinOutSet(PIR_IRA_S210ST01_LDO_SHDN_B_PORT,
+ PIR_IRA_S210ST01_LDO_SHDN_B_PIN);
+
+ pir_instance.opamp_mode = pir_init->opamp_mode;
+ pir_instance.motion_on_time = pir_init->motion_on_time;
+ pir_instance.win_size = pir_init->win_size;
+ pir_instance.motion_detection_callback = pir_init->motion_detection_callback;
+ pir_instance.adc_irq_callback = pir_init->adc_irq_callback;
+ pir_instance.use_timestamp = pir_init->use_timestamp;
+ if ((pir_instance.motion_detection_callback == NULL)
+ || (pir_instance.adc_irq_callback == NULL)) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+
+ app_queue.size = pir_init->sample_queue_size;
+ app_queue.sample = pir_init->sample_queue;
+ if (app_queue.size < 4) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+
+ adc_queue.size = ADC_SAMPLE_QUEUE_SIZE;
+ adc_queue.sample = adc_sample_queue;
+
+ // Peripheral initialization
+ if (pir_init->opamp_mode == pir_opamp_mode_internal) {
+ init_opamp();
+ }
+ if (pir_init->use_timestamp) {
+ init_timestamp_clock();
+ }
+ if (SL_STATUS_OK == init_adc(adc_enter_em2)) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+
+ // Default to motion off state
+ pir_instance.motion_detection_callback(false);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Starts PIR sensor sampling.
+ ******************************************************************************/
+sl_status_t pir_start(void)
+{
+ lockout_counter = 0;
+
+ ADC_Start(ADC0, adcStartSingle);
+ // Wake up on FIFO reaching threshold.
+ ADC_IntEnable(ADC0, ADC_IF_SINGLE);
+ // Wake up on ADC exceeding window threshold.
+ ADC_IntEnable(ADC0, ADC_IF_SINGLECMP);
+ NVIC_EnableIRQ(ADC0_IRQn);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Stops PIR sensor sampling.
+ ******************************************************************************/
+sl_status_t pir_stop(void)
+{
+ ADC_IntDisable(ADC0, ADC_IF_SINGLE);
+ ADC_IntDisable(ADC0, ADC_IF_SINGLECMP);
+ NVIC_DisableIRQ(ADC0_IRQn);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Runs the motion detection algorithm
+ *
+ * @note
+ * This algorithms takes roughly 150us and must run on the latest ADC sample
+ * after receiving the ADC interrupt.
+ ******************************************************************************/
+sl_status_t pir_detect_motion(void)
+{
+ bool motion = false;
+ uint32_t num_of_samples = 0;
+ pir_sample_t adc_sample;
+ pir_sample_t pir_sample;
+ int32_t adc_thresh_high, adc_thresh_low;
+
+ // Read out each ADC sample, update the LPF mean, and check if it was within
+ // the window thresholds
+ while (adc_queue.used > 0) {
+ num_of_samples++;
+ dequeue_sample(&adc_queue, &adc_sample);
+ // Capture the ADC and winBase of the current sample.
+ pir_sample.adc_sample = adc_sample.adc_sample;
+ pir_sample.win_base = win_base;
+#if PIR_SOURCE == PIR_SOURCE_DIFF
+ adc_thresh_high =
+ ((int16_t) ((ADC0->CMPTHR & _ADC_CMPTHR_ADGT_MASK) >>
+ _ADC_CMPTHR_ADGT_SHIFT));
+ adc_thresh_low =
+ ((int16_t) ((ADC0->CMPTHR & _ADC_CMPTHR_ADLT_MASK) >>
+ _ADC_CMPTHR_ADLT_SHIFT));
+#elif PIR_SOURCE == PIR_SOURCE_POS || PIR_SOURCE == PIR_SOURCE_NEG
+ adc_thresh_high =
+ ((uint16_t) ((ADC0->CMPTHR & _ADC_CMPTHR_ADGT_MASK) >>
+ _ADC_CMPTHR_ADGT_SHIFT));
+ adc_thresh_low =
+ ((uint16_t) ((ADC0->CMPTHR & _ADC_CMPTHR_ADLT_MASK) >>
+ _ADC_CMPTHR_ADLT_SHIFT));
+#endif
+
+ // If window was broken, move window thresholds to include the latest ADC
+ // reading.
+ // Thresholds are recalculated in software because samples are batch
+ // processed.
+ if (adc_sample.adc_sample > adc_thresh_high) {
+ win_base = adc_sample.adc_sample - pir_instance.win_size / 2;
+ motion = true;
+ } else if (adc_sample.adc_sample < adc_thresh_low) {
+ win_base = adc_sample.adc_sample + pir_instance.win_size / 2;
+ motion = true;
+ } else {
+ // Window was not broken, update winBase to follow the low frequency drift
+ // using a DT 1st order LPF.
+ // Let a = 2^-a_shift
+ // Equivalent continuous RC is given by Ts * (1-a) / a
+ uint32_t a_shift = 5;
+ win_base =
+ (adc_sample.adc_sample >> a_shift) + (win_base - (win_base >> a_shift));
+ }
+
+ update_adc_thresholds(win_base, pir_instance.win_size);
+
+ // Enqueue the PIR sample
+ pir_sample.timestamp_ms = adc_sample.timestamp_ms;
+ pir_sample.motion_status = (lockout_counter > 0 || motion);
+ pir_sample.adc_upper_threshold = adc_thresh_high;
+ pir_sample.adc_lower_threshold = adc_thresh_low;
+ enqueue_sample(&app_queue, pir_sample);
+ } // while (data_valid)
+
+ if (lockout_counter > 0) {
+ lockout_counter -=
+ (num_of_samples < lockout_counter) ? num_of_samples : lockout_counter;
+ if (lockout_counter == 0) {
+ // Motion off
+ pir_instance.motion_detection_callback(false);
+ }
+ }
+
+ // Motion On
+ if (motion) {
+ lockout_counter = pir_instance.motion_on_time * 32; // 32Hz
+ pir_instance.motion_detection_callback(true);
+ }
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * ADC interrupt handler
+ ******************************************************************************/
+void ADC0_IRQHandler(void)
+{
+ uint32_t flags;
+ pir_sample_t adc_sample;
+ static int32_t last_timestamp = -1;
+
+ flags = ADC_IntGetEnabled(ADC0);
+ ADC_IntClear(ADC0, flags);
+ NVIC_ClearPendingIRQ(ADC0_IRQn);
+
+ // Enqueue the ADC sample
+ while (ADC0->SINGLEFIFOCOUNT > 0)
+ {
+ if ((last_timestamp < 0) && pir_instance.use_timestamp) {
+ last_timestamp = ~LETIMER_CounterGet(LETIMER0);
+ }
+ // adjust this with over-sampling for OSR < 64. Need to left shift to get to
+ // 16b.
+ adc_sample.adc_sample = ADC_DataSingleGet(ADC0) << 3;
+ adc_sample.timestamp_ms = last_timestamp;
+ enqueue_sample(&adc_queue, adc_sample);
+ }
+
+ pir_instance.adc_irq_callback();
+}
+
+/***************************************************************************//**
+ * @brief
+ * Reads out a sample from the PIR sample queue.
+ *
+ * @param[out] pir_sample
+ * Pointer to the PIR sample
+ ******************************************************************************/
+sl_status_t pir_read_queue(pir_sample_t *pir_sample)
+{
+ if (app_queue.sample == NULL) {
+ return SL_STATUS_FAIL;
+ }
+ dequeue_sample(&app_queue, pir_sample);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Gets number of samples in the queue.
+ *
+ * @return
+ * The number of samples in the queue.
+ ******************************************************************************/
+sl_status_t pir_get_queue_size(uint16_t *size)
+{
+ if ((app_queue.sample == NULL) || (app_queue.used == 0)) {
+ *size = 0;
+ return SL_STATUS_FAIL;
+ } else {
+ *size = app_queue.used;
+ }
+
+ return SL_STATUS_OK;
+}
diff --git a/driver/public/silabs/pir_ira_s210st01/src/pir_ira_s210st01_s2.c b/driver/public/silabs/pir_ira_s210st01/src/pir_ira_s210st01_s2.c
new file mode 100644
index 00000000..92a8a19d
--- /dev/null
+++ b/driver/public/silabs/pir_ira_s210st01/src/pir_ira_s210st01_s2.c
@@ -0,0 +1,752 @@
+/***************************************************************************//**
+ * @file
+ * @brief PIR driver.
+ * @version 1.0.2
+ *******************************************************************************
+ * # License
+ * Copyright 2019 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * The licensor of this software is Silicon Laboratories Inc. Your use of this
+ * software is governed by the terms of Silicon Labs Master Software License
+ * Agreement (MSLA) available at
+ * www.silabs.com/about-us/legal/master-software-license-agreement. This
+ * software is distributed to you in Source Code format and is governed by the
+ * sections of the MSLA applicable to Source Code.
+ *
+ ******************************************************************************/
+#include "em_cmu.h"
+#include "em_emu.h"
+#include "em_gpio.h"
+#include "em_iadc.h"
+#include "em_letimer.h"
+
+#include
+#include
+#include
+#include
+
+#define ADC_PERIPHERAL IADC0
+#define ADC_CLOCK cmuClock_IADC0
+
+// Set CLK_ADC to 10 MHz
+#define CLK_SRC_ADC_FREQ 5000000 // CLK_SRC_ADC
+#define CLK_ADC_FREQ 1000000 // CLK_ADC - 10 MHz max in normal mode
+
+// Desired Sampling frequency in Hz
+#define SAMPLING_FREQ 32
+#define ADC_SAMPLING_FREQ 96
+
+// Set IADC timer cycles
+#define ADC_TIMER_CYCLES (CLK_SRC_ADC_FREQ / ADC_SAMPLING_FREQ)
+
+#define ADC_SAMPLE_QUEUE_SIZE 4 // Must be at least 4
+
+/// The adcSource variable should be set to adcSourceAdcDiff for PIR operation.
+/// The single ended modes are additional modes for signal chain analysis with a
+/// voltage source.
+#define PIR_SOURCE_POS 0
+#define PIR_SOURCE_NEG 1
+#define PIR_SOURCE_DIFF 2
+#if defined(PIR_IRA_S210ST01_ADC_P_PORT) && \
+ defined(PIR_IRA_S210ST01_ADC_P_PIN) && \
+ defined(PIR_IRA_S210ST01_ADC_N_PORT) && \
+ defined(PIR_IRA_S210ST01_ADC_N_PIN)
+#define PIR_SOURCE PIR_SOURCE_DIFF
+#elif defined(PIR_IRA_S210ST01_ADC_P_PORT) && \
+ defined(PIR_IRA_S210ST01_ADC_P_PIN)
+#define PIR_SOURCE PIR_SOURCE_POS
+#else
+#define PIR_SOURCE PIR_SOURCE_NEG
+#error "The posInput of the ADC is not defined for the kit, only the negInput"
+#endif
+
+#define adc_mux_even(ref, adc, bus, index) \
+ GPIO->bus ## BUSALLOC |= \
+ GPIO_ ## bus ## BUSALLOC_ ## bus ## EVEN ## index ## _ ## adc;
+#define adc_mux_odd(ref, adc, bus, index) \
+ GPIO->bus ## BUSALLOC |= \
+ GPIO_ ## bus ## BUSALLOC_ ## bus ## ODD ## index ## _ ## adc;
+
+/// PIR sample queue structure
+typedef struct {
+ volatile uint16_t head; ///< Index of next byte to get.
+ volatile uint16_t tail; ///< Index of where to enqueue next
+ ///< byte.
+ volatile uint16_t used; ///< Number of bytes queued.
+ uint16_t size; ///< Size of queue.
+ pir_sample_t *sample; ///< Pointer to PIR sample buffer.
+} sample_queue_t;
+
+static pir_init_t pir_instance; // An instance that holds the configuration
+static uint32_t lockout_counter = 0; // The time, in samples, remaining on the
+ // lockout window after detection.
+static int32_t win_base = 0; // The low frequency mean of the PIR input
+ // signal.
+
+static int32_t pos_thresh = 0;
+static int32_t neg_thresh = 0;
+
+static sample_queue_t app_queue; // Buffer PIR samples for application layer
+ // debugging.
+static sample_queue_t adc_queue; // Buffer ADC samples for motion detection
+ // algorithm.
+static pir_sample_t adc_sample_queue[ADC_SAMPLE_QUEUE_SIZE]; // ADC sample
+ // buffer.
+
+#if PIR_SOURCE == PIR_SOURCE_DIFF || PIR_SOURCE == PIR_SOURCE_POS
+static sl_status_t allocate_analog_bus_even0(IADC_TypeDef *iadc,
+ GPIO_Port_TypeDef port)
+{
+ switch (port) {
+ case gpioPortA:
+#if (IADC_COUNT == 1)
+ if (iadc == IADC0) {
+ adc_mux_even(iadc, ADC0, A, 0);
+ return SL_STATUS_OK;
+#elif (IADC_COUNT == 2)
+ } else if (iadc == IADC1) {
+ adc_mux_even(iadc, ADC1, A, 0);
+ return SL_STATUS_OK;
+#endif
+ } else {
+ return SL_STATUS_FAIL;
+ }
+
+ case gpioPortB:
+#if (IADC_COUNT == 1)
+ if (iadc == IADC0) {
+ adc_mux_even(iadc, ADC0, B, 0);
+ return SL_STATUS_OK;
+#elif (IADC_COUNT == 2)
+ } else if (iadc == IADC1) {
+ adc_mux_even(iadc, ADC1, B, 0);
+ return SL_STATUS_OK;
+#endif
+ } else {
+ return SL_STATUS_FAIL;
+ }
+
+ case gpioPortC:
+ case gpioPortD:
+#if (IADC_COUNT == 1)
+ if (iadc == IADC0) {
+ adc_mux_even(iadc, ADC0, CD, 0);
+ return SL_STATUS_OK;
+#elif (IADC_COUNT == 2)
+ } else if (iadc == IADC1) {
+ adc_mux_even(iadc, ADC1, CD, 0);
+ return SL_STATUS_OK;
+#endif
+ } else {
+ return SL_STATUS_FAIL;
+ }
+
+ default:
+ return SL_STATUS_FAIL;
+ }
+}
+
+#endif
+
+#if PIR_SOURCE == PIR_SOURCE_DIFF || PIR_SOURCE == PIR_SOURCE_NEG
+static sl_status_t allocate_analog_bus_odd0(IADC_TypeDef *iadc,
+ GPIO_Port_TypeDef port)
+{
+ switch (port) {
+ case gpioPortA:
+#if (IADC_COUNT == 1)
+ if (iadc == IADC0) {
+ adc_mux_odd(iadc, ADC0, A, 0);
+ return SL_STATUS_OK;
+#elif (IADC_COUNT == 2)
+ } else if (iadc == IADC1) {
+ adc_mux_odd(iadc, ADC1, A, 0);
+ return SL_STATUS_OK;
+#endif
+ } else {
+ return SL_STATUS_FAIL;
+ }
+
+ case gpioPortB:
+#if (IADC_COUNT == 1)
+ if (iadc == IADC0) {
+ adc_mux_odd(iadc, ADC0, B, 0);
+ return SL_STATUS_OK;
+#elif (IADC_COUNT == 2)
+ } else if (iadc == IADC1) {
+ adc_mux_odd(iadc, ADC1, B, 0);
+ return SL_STATUS_OK;
+#endif
+ } else {
+ return SL_STATUS_FAIL;
+ }
+
+ case gpioPortC:
+ case gpioPortD:
+#if (IADC_COUNT == 1)
+ if (iadc == IADC0) {
+ adc_mux_odd(iadc, ADC0, CD, 0);
+ return SL_STATUS_OK;
+#elif (IADC_COUNT == 2)
+ } else if (iadc == IADC1) {
+ adc_mux_odd(iadc, ADC1, CD, 0);
+ return SL_STATUS_OK;
+#endif
+ } else {
+ return SL_STATUS_FAIL;
+ }
+
+ default:
+ return SL_STATUS_FAIL;
+ }
+}
+
+#endif
+
+/***************************************************************************//**
+ * @brief
+ * Updates the ADC hardware thresholds for a motion event trigger.
+ *
+ * Inputs must mast the conversion data representation. For oversampled
+ * conversions, the resolution is 16-bit, regardless if the OVS setting
+ * does not achieve 16-bit resolution.
+ *
+ * @param[in] win_base
+ * The midpoint of the window. Thresholds are the base +/- 0.5*winSize
+ *
+ * @param[in] win_size
+ * The total peak to peak width of the window.
+ ******************************************************************************/
+static void update_adc_thresholds(int32_t win_base, uint32_t win_size)
+{
+ pos_thresh = win_base + win_size / 2;
+ neg_thresh = win_base - win_size / 2;
+
+ // Ensure thresholds are within int16_t for ADC window comparator.
+ int32_t pos_thresh_max, neg_thresh_min;
+#if PIR_SOURCE == PIR_SOURCE_DIFF
+ pos_thresh_max = 32767;
+ neg_thresh_min = -32768;
+#else
+ pos_thresh_max = 65535;
+ neg_thresh_min = 0;
+#endif
+
+ if (pos_thresh > pos_thresh_max) {
+ pos_thresh = pos_thresh_max;
+ }
+ if (neg_thresh < neg_thresh_min) {
+ neg_thresh = neg_thresh_min;
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Initializes the ADC, CRYOTIMER and PRS for PIR operation.
+ *
+ * @details
+ * PRS triggering of the ADC in EM2 is only possible on > Series 1 MCUs.
+ *
+ * @param[in] adc_enter_em2
+ * Sets up ADC to run in EM2 when set to true.
+ ******************************************************************************/
+static sl_status_t init_adc(bool adc_enter_em2)
+{
+ // Declare initialization structures
+ IADC_Init_t adcInit = IADC_INIT_DEFAULT;
+ IADC_AllConfigs_t initAllConfigs = IADC_ALLCONFIGS_DEFAULT;
+ IADC_InitSingle_t initSingle = IADC_INITSINGLE_DEFAULT;
+ // Single input structure
+ IADC_SingleInput_t adcInitSingle = IADC_SINGLEINPUT_DEFAULT;
+
+ CMU_ClockEnable(ADC_CLOCK, true);
+
+ // Reset IADC to reset configuration in case it has been modified
+ IADC_reset(ADC_PERIPHERAL);
+
+ // Use the FSRC0 as the IADC clock so it can run in EM2
+ CMU_ClockSelectSet(ADC_CLOCK, cmuSelect_FSRCO);
+
+ // Set the prescaler needed for the intended IADC clock frequency
+ adcInit.srcClkPrescale = IADC_calcSrcClkPrescale(ADC_PERIPHERAL,
+ CLK_SRC_ADC_FREQ,
+ 0);
+
+ // Shutdown between conversions to reduce current
+ adcInit.warmup = iadcWarmupNormal;
+
+ // Set timer cycles to configure sampling rate
+#if ADC_TIMER_CYCLES > 65535
+ adcInit.timerCycles = 65535;
+#else
+ adcInit.timerCycles = ADC_TIMER_CYCLES;
+#endif
+
+ /*
+ * Configuration 0 is used by both scan and single conversions by
+ * default. Use internal bandgap as the reference and specify the
+ * reference voltage in mV.
+ *
+ * Resolution is not configurable directly but is based on the
+ * selected oversampling ratio (osrHighSpeed), which defaults to
+ * 2x and generates 12-bit results.
+ */
+ initAllConfigs.configs[0].reference = iadcCfgReferenceVddx;
+ initAllConfigs.configs[0].vRef = 3300;
+ initAllConfigs.configs[0].osrHighSpeed = iadcCfgOsrHighSpeed2x;
+ initAllConfigs.configs[0].analogGain = iadcCfgAnalogGain1x;
+
+ /*
+ * CLK_SRC_ADC is prescaled to derive the intended CLK_ADC frequency.
+ *
+ * Based on the default 2x oversampling rate (OSRHS)...
+ *
+ * conversion time = ((4 * OSRHS) + 2) / fCLK_ADC
+ *
+ * ...which, results in a maximum sampling rate of 833 ksps with the
+ * 2-clock input multiplexer switching time is included.
+ */
+ initAllConfigs.configs[0].adcClkPrescale = IADC_calcAdcClkPrescale(
+ ADC_PERIPHERAL,
+ CLK_ADC_FREQ,
+ 0,
+ iadcCfgModeNormal,
+ adcInit.srcClkPrescale);
+#if PIR_SOURCE == PIR_SOURCE_POS
+ adcInitSingle.posInput = IADC_portPinToPosInput(PIR_IRA_S210ST01_ADC_P_PORT,
+ PIR_IRA_S210ST01_ADC_P_PIN);
+ adcInitSingle.negInput = iadcNegInputGnd;
+
+ // Allocate the analog bus for ADC inputs
+ if (SL_STATUS_OK != allocate_analog_bus_even0(ADC_PERIPHERAL,
+ PIR_IRA_S210ST01_ADC_P_PORT)) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+#elif PIR_SOURCE == PIR_SOURCE_NEG
+ // The posSel of the ADC_N is not defined for the kit, only the negSel.
+ adcInitSingle.posInput = iadcPosInputAvdd;
+ adcInitSingle.negInput = IADC_portPinToNegInput(PIR_IRA_S210ST01_ADC_N_PORT,
+ PIR_IRA_S210ST01_ADC_N_PIN);
+
+ // Allocate the analog bus for ADC inputs
+ if (SL_STATUS_OK != allocate_analog_bus_odd0(ADC_PERIPHERAL,
+ PIR_IRA_S210ST01_ADC_N_PORT)) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+#elif PIR_SOURCE == PIR_SOURCE_DIFF
+ adcInitSingle.posInput = IADC_portPinToPosInput(PIR_IRA_S210ST01_ADC_P_PORT,
+ PIR_IRA_S210ST01_ADC_P_PIN);
+ adcInitSingle.negInput = IADC_portPinToNegInput(PIR_IRA_S210ST01_ADC_N_PORT,
+ PIR_IRA_S210ST01_ADC_N_PIN);
+
+ // Allocate the analog bus for ADC inputs
+ if (SL_STATUS_OK != allocate_analog_bus_even0(ADC_PERIPHERAL,
+ PIR_IRA_S210ST01_ADC_P_PORT)) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+ if (SL_STATUS_OK != allocate_analog_bus_odd0(ADC_PERIPHERAL,
+ PIR_IRA_S210ST01_ADC_N_PORT)) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+#endif
+
+ // Single initialization
+ initSingle.triggerSelect = iadcTriggerSelTimer;
+
+ // Enable triggering of single conversion
+ initSingle.start = true;
+
+ // Initialize IADC
+ IADC_init(ADC_PERIPHERAL, &adcInit, &initAllConfigs);
+
+ // Initialize a single-channel conversion
+ IADC_initSingle(ADC_PERIPHERAL, &initSingle, &adcInitSingle);
+
+ // Clear any previous interrupt flags
+ IADC_clearInt(ADC_PERIPHERAL, _IADC_IF_MASK);
+
+ // Enable single-channel done interrupts
+ IADC_enableInt(ADC_PERIPHERAL, IADC_IEN_SINGLEDONE);
+
+ // Enable IADC interrupts
+ NVIC_ClearPendingIRQ(IADC_IRQn);
+ NVIC_EnableIRQ(IADC_IRQn);
+
+ update_adc_thresholds(win_base, pir_instance.win_size);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Initialize GPIO.
+ ******************************************************************************/
+static void init_gpio(void)
+{
+ CMU_ClockEnable(cmuClock_GPIO, true);
+ GPIO_PinModeSet(PIR_IRA_S210ST01_LDO_SHDN_B_PORT,
+ PIR_IRA_S210ST01_LDO_SHDN_B_PIN,
+ gpioModePushPull,
+ 0);
+#if defined(PIR_IRA_S210ST01_ADC_P_PORT) && \
+ defined(PIR_IRA_S210ST01_ADC_P_PIN)
+ // ADC_P
+ GPIO_PinModeSet(PIR_IRA_S210ST01_ADC_P_PORT,
+ PIR_IRA_S210ST01_ADC_P_PIN,
+ gpioModeDisabled,
+ 0);
+#endif
+#if defined(PIR_IRA_S210ST01_ADC_N_PORT) && \
+ defined(PIR_IRA_S210ST01_ADC_N_PIN)
+ // ADC_N
+ GPIO_PinModeSet(PIR_IRA_S210ST01_ADC_N_PORT,
+ PIR_IRA_S210ST01_ADC_N_PIN,
+ gpioModeDisabled,
+ 0);
+#endif
+}
+
+/***************************************************************************//**
+ * @brief
+ * Initialize timers for time stamping samples to the GUI.
+ *
+ * @details
+ * LETIMER0 will operate at 1024 Hz time stamp clock.
+ ******************************************************************************/
+
+/***************************************************************************//**
+ * @brief
+ * Initialize timers for time stamping samples to the GUI.
+ *
+ * @details
+ * LETIMER0 will operate at 1024 Hz time stamp clock.
+ ******************************************************************************/
+static void init_timestamp_clock(void)
+{
+ CMU_LFXOInit_TypeDef lfxoInit = CMU_LFXOINIT_DEFAULT;
+ LETIMER_Init_TypeDef letimerInit = LETIMER_INIT_DEFAULT;
+
+ // Initialize the LFXO and use it as the EM23GRPACLK source
+ CMU_LFXOInit(&lfxoInit);
+ CMU_ClockSelectSet(cmuClock_EM23GRPACLK, cmuSelect_LFXO);
+ CMU_ClockEnable(cmuClock_LETIMER0, true);
+
+ LETIMER_Init(LETIMER0, &letimerInit);
+
+// // Clear any previous interrupt flags
+// LETIMER_IntClear(LETIMER0, _LETIMER_IF_MASK);
+//
+// // Enable underflow interrupts
+// LETIMER_IntEnable(LETIMER0, LETIMER_IEN_UF);
+//
+// // Enable LETIMER interrupts
+// NVIC_ClearPendingIRQ(LETIMER0_IRQn);
+// NVIC_EnableIRQ(LETIMER0_IRQn);
+}
+
+/***************************************************************************//**
+ * @brief
+ * Enqueue the PIR sample.
+ ******************************************************************************/
+static void enqueue_sample(sample_queue_t *queue, pir_sample_t sample)
+{
+ queue->sample[queue->head] = sample;
+ queue->head++;
+ if (queue->head == queue->size) {
+ queue->head = 0;
+ }
+ queue->used++;
+
+ if (queue->head == queue->tail) {
+ // If buffer is full, drop the oldest sample in the circular buffer and
+ // update the tail pointer.
+ queue->tail++;
+ if (queue->tail == queue->size) {
+ queue->tail = 0;
+ }
+ queue->used = queue->size;
+ }
+}
+
+/***************************************************************************//**
+ * @brief
+ * Dequeue the PIR sample.
+ ******************************************************************************/
+static void dequeue_sample(sample_queue_t *queue, pir_sample_t *sample)
+{
+ if (queue->used < 1) {
+ sample = NULL;
+ }
+
+ *sample = queue->sample[queue->tail];
+ queue->tail++;
+ if (queue->tail == queue->size) {
+ queue->tail = 0;
+ }
+ queue->used -= 1;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Initializes peripherals for PIR
+ *
+ * @param[in] pir_init
+ * A pointer to PIR initialization structure
+ *
+ * @param[in] adc_enter_em2
+ * Sets up ADC to run in EM2 when set to true
+ ******************************************************************************/
+sl_status_t pir_init(pir_init_t *pir_init, bool adc_enter_em2)
+{
+ init_gpio();
+ // Enable LDO to startup VPIR.
+ GPIO_PinOutSet(PIR_IRA_S210ST01_LDO_SHDN_B_PORT,
+ PIR_IRA_S210ST01_LDO_SHDN_B_PIN);
+
+ pir_instance.opamp_mode = pir_init->opamp_mode;
+ pir_instance.motion_on_time = pir_init->motion_on_time;
+ pir_instance.win_size = pir_init->win_size;
+ pir_instance.motion_detection_callback = pir_init->motion_detection_callback;
+ pir_instance.adc_irq_callback = pir_init->adc_irq_callback;
+ pir_instance.use_timestamp = pir_init->use_timestamp;
+ if ((pir_instance.motion_detection_callback == NULL)
+ || (pir_instance.adc_irq_callback == NULL)) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+
+ app_queue.size = pir_init->sample_queue_size;
+ app_queue.sample = pir_init->sample_queue;
+ if (app_queue.size < 4) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+
+ adc_queue.size = ADC_SAMPLE_QUEUE_SIZE;
+ adc_queue.sample = adc_sample_queue;
+
+ // Peripheral initialization
+ if (pir_init->opamp_mode == pir_opamp_mode_internal) {
+ return SL_STATUS_NOT_SUPPORTED;
+ }
+
+ if (pir_init->use_timestamp) {
+ init_timestamp_clock();
+ }
+
+ if (SL_STATUS_OK != init_adc(adc_enter_em2)) {
+ return SL_STATUS_INVALID_CONFIGURATION;
+ }
+
+ // Default to motion off state
+ pir_instance.motion_detection_callback(false);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Starts PIR sensor sampling.
+ ******************************************************************************/
+sl_status_t pir_start(void)
+{
+ lockout_counter = 0;
+
+ // Clear any previous interrupt flags
+ IADC_clearInt(ADC_PERIPHERAL, _IADC_IF_MASK);
+
+ // Enable single-channel done interrupts
+ IADC_enableInt(ADC_PERIPHERAL, IADC_IEN_SINGLEDONE);
+
+ // Enable IADC interrupts
+ NVIC_ClearPendingIRQ(IADC_IRQn);
+ NVIC_EnableIRQ(IADC_IRQn);
+
+ // IADC single already enabled; must enable timer block in order to trigger
+ IADC_command(ADC_PERIPHERAL, iadcCmdEnableTimer);
+
+// // Enable underflow interrupts
+// LETIMER_IntEnable(LETIMER0, LETIMER_IEN_UF);
+//
+// // Enable LETIMER interrupts
+// NVIC_ClearPendingIRQ(LETIMER0_IRQn);
+// NVIC_EnableIRQ(LETIMER0_IRQn);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Stops PIR sensor sampling.
+ ******************************************************************************/
+sl_status_t pir_stop(void)
+{
+ // Disable single-channel done interrupts
+ IADC_disableInt(ADC_PERIPHERAL, IADC_IEN_SINGLEDONE);
+
+ NVIC_DisableIRQ(IADC_IRQn);
+
+ // Stop an IADC conversion
+ IADC_command(ADC_PERIPHERAL, iadcCmdDisableTimer);
+
+// // Disable underflow interrupts
+// LETIMER_IntDisable(LETIMER0, LETIMER_IEN_UF);
+//
+// // Disable LETIMER interrupts
+// NVIC_DisableIRQ(LETIMER0_IRQn);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Runs the motion detection algorithm
+ *
+ * @note
+ * This algorithms takes roughly 150us and must run on the latest ADC sample
+ * after receiving the ADC interrupt.
+ ******************************************************************************/
+sl_status_t pir_detect_motion(void)
+{
+ bool motion = false;
+ uint32_t num_of_samples = 0;
+ pir_sample_t adc_sample;
+ pir_sample_t pir_sample;
+
+ // Read out each ADC sample, update the LPF mean, and check if it was within
+ // the window thresholds
+ while (adc_queue.used > 0) {
+ num_of_samples++;
+ dequeue_sample(&adc_queue, &adc_sample);
+ // Capture the ADC and winBase of the current sample.
+ pir_sample.adc_sample = adc_sample.adc_sample;
+ pir_sample.win_base = win_base;
+
+ // If window was broken, move window thresholds to include the latest ADC
+ // reading.
+ // Thresholds are recalculated in software because samples are batch
+ // processed.
+ if (adc_sample.adc_sample > pos_thresh) {
+ win_base = adc_sample.adc_sample - pir_instance.win_size / 2;
+ motion = true;
+ } else if (adc_sample.adc_sample < neg_thresh) {
+ win_base = adc_sample.adc_sample + pir_instance.win_size / 2;
+ motion = true;
+ } else {
+ // Window was not broken, update winBase to follow the low frequency drift
+ // using a DT 1st order LPF.
+ // Let a = 2^-a_shift
+ // Equivalent continuous RC is given by Ts * (1-a) / a
+ uint32_t a_shift = 5;
+ win_base =
+ (adc_sample.adc_sample >> a_shift) + (win_base - (win_base >> a_shift));
+ }
+
+ update_adc_thresholds(win_base, pir_instance.win_size);
+
+ // Enqueue the PIR sample
+ pir_sample.timestamp_ms = adc_sample.timestamp_ms;
+ pir_sample.motion_status = (lockout_counter > 0 || motion);
+ pir_sample.adc_upper_threshold = pos_thresh;
+ pir_sample.adc_lower_threshold = neg_thresh;
+ enqueue_sample(&app_queue, pir_sample);
+ } // while (data_valid)
+
+ if (lockout_counter > 0) {
+ lockout_counter -=
+ (num_of_samples < lockout_counter) ? num_of_samples : lockout_counter;
+ if (lockout_counter == 0) {
+ // Motion off
+ pir_instance.motion_detection_callback(false);
+ }
+ }
+
+ // Motion On
+ if (motion) {
+ lockout_counter = pir_instance.motion_on_time * 32; // 32Hz
+ pir_instance.motion_detection_callback(true);
+ }
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * ADC interrupt handler
+ ******************************************************************************/
+void IADC_IRQHandler(void)
+{
+ pir_sample_t adc_sample;
+ static int32_t last_timestamp = -1;
+ static uint8_t irq_count = 0;
+
+ IADC_clearInt(ADC_PERIPHERAL, IADC_IF_SINGLEDONE);
+ NVIC_ClearPendingIRQ(IADC_IRQn);
+
+ // IADC_Result_t sample = IADC_pullSingleFifoResult(ADC_PERIPHERAL);
+ IADC_Result_t sample = IADC_readSingleResult(ADC_PERIPHERAL);
+ if ((++irq_count % (ADC_SAMPLING_FREQ / SAMPLING_FREQ)) == 0) {
+ // Enqueue the ADC sample
+ if ((last_timestamp < 0) && pir_instance.use_timestamp) {
+ last_timestamp = ~LETIMER_CounterGet(LETIMER0);
+ }
+
+ // adjust this with over-sampling for OSR < 64. Need to left shift to get to
+ // 16b.
+ adc_sample.adc_sample = sample.data << 3;
+ adc_sample.timestamp_ms = last_timestamp;
+ enqueue_sample(&adc_queue, adc_sample);
+
+ pir_instance.adc_irq_callback();
+ irq_count = 0;
+ }
+}
+
+/**************************************************************************//**
+ * @brief LETIMER IRQ Handler
+ *****************************************************************************/
+void LETIMER0_IRQHandler(void)
+{
+ uint32_t flags = LETIMER_IntGet(LETIMER0);
+
+ // Trigger an IADC scan conversion
+// IADC_command(ADC_PERIPHERAL, iadcCmdStartSingle);
+
+ // Clear LETIMER interrupt flags
+ LETIMER_IntClear(LETIMER0, flags);
+}
+
+/***************************************************************************//**
+ * @brief
+ * Reads out a sample from the PIR sample queue.
+ *
+ * @param[out] pir_sample
+ * Pointer to the PIR sample
+ ******************************************************************************/
+sl_status_t pir_read_queue(pir_sample_t *pir_sample)
+{
+ if (app_queue.sample == NULL) {
+ return SL_STATUS_FAIL;
+ }
+ dequeue_sample(&app_queue, pir_sample);
+
+ return SL_STATUS_OK;
+}
+
+/***************************************************************************//**
+ * @brief
+ * Gets number of samples in the queue.
+ *
+ * @return
+ * The number of samples in the queue.
+ ******************************************************************************/
+sl_status_t pir_get_queue_size(uint16_t *size)
+{
+ if ((app_queue.sample == NULL) || (app_queue.used == 0)) {
+ *size = 0;
+ return SL_STATUS_FAIL;
+ } else {
+ *size = app_queue.used;
+ }
+
+ return SL_STATUS_OK;
+}
diff --git a/driver/public/silabs/services_fatfs/config/ffconf.h b/driver/public/silabs/services_fatfs/config/ffconf.h
new file mode 100644
index 00000000..ef404fc0
--- /dev/null
+++ b/driver/public/silabs/services_fatfs/config/ffconf.h
@@ -0,0 +1,396 @@
+/***************************************************************************//**
+ * @file ffconf.h
+ * @brief fatfs config file
+ * @version 1.0.0
+ *******************************************************************************
+ * # License
+ * Copyright 2022 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided \'as-is\', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ *******************************************************************************
+ *
+ * EVALUATION QUALITY
+ * This code has been minimally tested to ensure that it builds with the
+ * specified dependency versions and is suitable as a demonstration for
+ * evaluation purposes only.
+ * This code will be maintained at the sole discretion of Silicon Labs.
+ *
+ ******************************************************************************/
+#ifndef FFCONF_H_
+#define FFCONF_H_
+/*---------------------------------------------------------------------------/
+/ Configurations of FatFs Module
+/---------------------------------------------------------------------------*/
+
+#define FFCONF_DEF 80286 /* Revision ID */
+
+/*---------------------------------------------------------------------------/
+/ Function Configurations
+/---------------------------------------------------------------------------*/
+// <<< Use Configuration Wizard in Context Menu >>>
+// Configurations of FatFs Module
+
+// Enable read-only file system. <0-1>
+// This option switches read-only configuration. (0:Read/Write or 1:Read-only)
+// Read-only configuration removes writing API functions, f_write(), f_sync(),
+// f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
+// and optional writing functions as well.
+// Default: 0
+#define FF_FS_READONLY 0
+
+// Define minimization level to remove some basic API functions. <0-3>
+#define FF_FS_MINIMIZE 0
+// This option defines minimization level to remove some basic API functions.
+//
+// 0: Basic functions are fully enabled.
+// 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
+// are removed.
+// 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
+// 3: f_lseek() function is removed in addition to 2.
+
+// Filtered directory read functions option. <0-2>
+#define FF_USE_FIND 0
+// This option switches filtered directory read functions, f_findfirst() and
+// f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too)
+
+// Enable f_mkfs() function. <0-1>
+#define FF_USE_MKFS 0
+// This option switches f_mkfs() function. (0:Disable or 1:Enable)
+
+// Enable fast seek function. <0-1>
+#define FF_USE_FASTSEEK 0
+// This option switches fast seek function. (0:Disable or 1:Enable)
+
+// Enable f_expand() function. <0-1>
+#define FF_USE_EXPAND 0
+// This option switches f_expand function. (0:Disable or 1:Enable)
+
+// Enable f_chmod() and f_utime() function. <0-1>
+#define FF_USE_CHMOD 0
+// This option switches attribute manipulation functions, f_chmod() and f_utime().
+// (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option.
+
+// Enable f_getlabel() and f_setlabel() function. <0-1>
+#define FF_USE_LABEL 0
+// This option switches volume label functions, f_getlabel() and f_setlabel().
+// (0:Disable or 1:Enable)
+
+// Enable f_forward() function. <0-1>
+#define FF_USE_FORWARD 0
+// This option switches f_forward() function. (0:Disable or 1:Enable)
+
+// String function option. <0-2>
+#define FF_USE_STRFUNC 0
+// FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and
+// f_printf().
+//
+// 0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect.
+// 1: Enable without LF-CRLF conversion.
+// 2: Enable with LF-CRLF conversion.
+
+// Enable f_printf() support long long argument. <0-1>
+// FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2
+#define FF_PRINT_LLI 1
+
+// Enable f_printf() support floating point argument. <0-1>
+// makes f_printf() support floating point argument. These features want C99 or later.
+#define FF_PRINT_FLOAT 1
+
+// Character encoding type. <0-3>
+//
+// When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character
+// encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE
+// to be read/written via those functions.
+//
+// 0: ANSI/OEM in current CP
+// 1: Unicode in UTF-16LE
+// 2: Unicode in UTF-16BE
+//