diff --git a/samples/boards/nxp/s32/psi5/CMakeLists.txt b/samples/boards/nxp/s32/psi5/CMakeLists.txt new file mode 100644 index 000000000000000..cc19ea188af9b77 --- /dev/null +++ b/samples/boards/nxp/s32/psi5/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(psi5) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/nxp/s32/psi5/boards/s32z2xxdc2_s32z270_rtu0.overlay b/samples/boards/nxp/s32/psi5/boards/s32z2xxdc2_s32z270_rtu0.overlay new file mode 100644 index 000000000000000..fab32e642cc8214 --- /dev/null +++ b/samples/boards/nxp/s32/psi5/boards/s32z2xxdc2_s32z270_rtu0.overlay @@ -0,0 +1,58 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + psi5_0_default: psi5_0_default { + group1 { + pinmux = , ; + output-enable; + }; + group2 { + pinmux = , ; + input-enable; + }; + }; +}; + +&psi5_0 { + pinctrl-0 = <&psi5_0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&psi5_0_ch1 { + target-pulse-us = <500>; + decoder-offset-us = <0>; + low-pulse-width-us = <100>; + high-pulse-width-us = <127>; + tx-mode = "long-frame-31"; + num-rx-buf = <32>; + rx-bitrate-kbps = <189>; + array-slot-duration-us = <150>; + array-slot-start-offset-us = <110>; + array-slot-data-length = <16>; + array-slot-data-msb-first = <0>; + array-slot-has-smc = <0>; + array-slot-has-parity = <0>; + status = "okay"; +}; + +&psi5_0_ch2 { + target-pulse-us = <8>; + decoder-offset-us = <0>; + low-pulse-width-us = <2>; + high-pulse-width-us = <6>; + tx-mode = "long-frame-31"; + num-rx-buf = <32>; + rx-bitrate-kbps = <189>; + array-slot-duration-us = <500>; + array-slot-start-offset-us = <0>; + array-slot-data-length = <16>; + array-slot-data-msb-first = <0>; + array-slot-has-smc = <0>; + array-slot-has-parity = <0>; + status = "okay"; +}; diff --git a/samples/boards/nxp/s32/psi5/boards/s32z2xxdc2_s32z270_rtu1.overlay b/samples/boards/nxp/s32/psi5/boards/s32z2xxdc2_s32z270_rtu1.overlay new file mode 100644 index 000000000000000..fab32e642cc8214 --- /dev/null +++ b/samples/boards/nxp/s32/psi5/boards/s32z2xxdc2_s32z270_rtu1.overlay @@ -0,0 +1,58 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + psi5_0_default: psi5_0_default { + group1 { + pinmux = , ; + output-enable; + }; + group2 { + pinmux = , ; + input-enable; + }; + }; +}; + +&psi5_0 { + pinctrl-0 = <&psi5_0_default>; + pinctrl-names = "default"; + status = "okay"; +}; + +&psi5_0_ch1 { + target-pulse-us = <500>; + decoder-offset-us = <0>; + low-pulse-width-us = <100>; + high-pulse-width-us = <127>; + tx-mode = "long-frame-31"; + num-rx-buf = <32>; + rx-bitrate-kbps = <189>; + array-slot-duration-us = <150>; + array-slot-start-offset-us = <110>; + array-slot-data-length = <16>; + array-slot-data-msb-first = <0>; + array-slot-has-smc = <0>; + array-slot-has-parity = <0>; + status = "okay"; +}; + +&psi5_0_ch2 { + target-pulse-us = <8>; + decoder-offset-us = <0>; + low-pulse-width-us = <2>; + high-pulse-width-us = <6>; + tx-mode = "long-frame-31"; + num-rx-buf = <32>; + rx-bitrate-kbps = <189>; + array-slot-duration-us = <500>; + array-slot-start-offset-us = <0>; + array-slot-data-length = <16>; + array-slot-data-msb-first = <0>; + array-slot-has-smc = <0>; + array-slot-has-parity = <0>; + status = "okay"; +}; diff --git a/samples/boards/nxp/s32/psi5/prj.conf b/samples/boards/nxp/s32/psi5/prj.conf new file mode 100644 index 000000000000000..bac255b3c7052b7 --- /dev/null +++ b/samples/boards/nxp/s32/psi5/prj.conf @@ -0,0 +1,3 @@ +CONFIG_PSI5=y +CONFIG_PSI5_LOG_LEVEL_DBG=y +CONFIG_LOG=y diff --git a/samples/boards/nxp/s32/psi5/sample.yaml b/samples/boards/nxp/s32/psi5/sample.yaml new file mode 100644 index 000000000000000..81ac63c0b838c14 --- /dev/null +++ b/samples/boards/nxp/s32/psi5/sample.yaml @@ -0,0 +1,14 @@ +sample: + description: Sample for using PSI5 driver + name: NXP S32 PSI5 sample + +tests: + sample.boards.nxp_s32.psi5: + platform_allow: + - s32z2xxdc2/s32z270/rtu0 + - s32z2xxdc2/s32z270/rtu1 + - s32z2xxdc2@D/s32z270/rtu0 + - s32z2xxdc2@D/s32z270/rtu1 + depends_on: psi5 + tags: psi5 + harness: console diff --git a/samples/boards/nxp/s32/psi5/src/main.c b/samples/boards/nxp/s32/psi5/src/main.c new file mode 100644 index 000000000000000..054facd695c1c21 --- /dev/null +++ b/samples/boards/nxp/s32/psi5/src/main.c @@ -0,0 +1,206 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(nxp_s32_psi5_sample, LOG_LEVEL_DBG); + +#include + +#include + +#define PSI5_NODE DT_INST(0, nxp_s32_psi5) + +/* Use pin B2 for simulate PSI5 signal from sensor to board */ + +#define GPIO_BASE 0x40521700 +#define MSRC_BASE 0x40520280 +#define GPIO_PIN 2 +#define GPIO_SET(val) sys_write16(BIT(15 - val), GPIO_BASE) + +void timing_delay_2_5_us(void) +{ + uint64_t start_cycles = arm_arch_timer_count(); + uint64_t cycles_to_wait = 20; + + for (;;) { + uint64_t current_cycles = arm_arch_timer_count(); + + if ((current_cycles - start_cycles) >= cycles_to_wait) { + break; + } + } +} + +/* Simulate a PSI5 message with 2 start bits, 16 data bits (0xAD2C), and 3 CRC bits (0x4). */ +void data_sensor_to_board_simulation(void) +{ + int key; + + sys_write32(BIT(21), MSRC_BASE + GPIO_PIN * 4); + key = irq_lock(); + + GPIO_SET(0); + timing_delay_2_5_us(); + timing_delay_2_5_us(); + timing_delay_2_5_us(); + timing_delay_2_5_us(); + + /* s1, s2 */ + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + /* 0011 */ + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + GPIO_SET(0); + timing_delay_2_5_us(); + + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + GPIO_SET(0); + timing_delay_2_5_us(); + + /* 0100 */ + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + GPIO_SET(0); + timing_delay_2_5_us(); + + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + /* 1011 */ + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + GPIO_SET(0); + timing_delay_2_5_us(); + + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + GPIO_SET(0); + timing_delay_2_5_us(); + + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + GPIO_SET(0); + timing_delay_2_5_us(); + + /* 0101 */ + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + GPIO_SET(0); + timing_delay_2_5_us(); + + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + GPIO_SET(0); + timing_delay_2_5_us(); + + /* CRC */ + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + GPIO_SET(0); + timing_delay_2_5_us(); + + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + GPIO_SET(0); + timing_delay_2_5_us(); + GPIO_SET(GPIO_PIN); + timing_delay_2_5_us(); + + GPIO_SET(0); + irq_unlock(key); +} + +void tx_cb(const struct device *dev, uint8_t channel_id, enum psi5_state state, void *user_data) +{ + LOG_INF("Tx channel %d completed\n", channel_id); +} + +void rx_cb(const struct device *dev, uint8_t channel_id, struct psi5_frame *frame, + enum psi5_state state, void *user_data) +{ + if (state == PSI5_STATE_MSG_RECEIVED) { + LOG_INF("Rx channel %d completed data (0x%x)\n", channel_id, frame->msg.data); + } else { + LOG_INF("Rx channel %d err (0x%x)\n", channel_id, state); + } +} + +int main(void) +{ + const struct device *const dev = DEVICE_DT_GET(PSI5_NODE); + uint64_t send_data = 0x1234; + + /* test receive data */ + psi5_add_rx_callback(dev, 1, rx_cb, NULL); + + psi5_start(dev, 1); + + /* delay generate data after pusle sync */ + k_busy_wait(100); + + data_sensor_to_board_simulation(); + + k_sleep(K_MSEC(1)); + + psi5_stop(dev, 1); + + /* test send data */ + psi5_start(dev, 2); + + psi5_send(dev, 2, send_data, K_MSEC(100), tx_cb, NULL); + + return 0; +}