Browse Source
Create test, sample for SENT driver Signed-off-by: Cong Nguyen Huu <cong.nguyenhuu@nxp.com>pull/89637/merge
13 changed files with 371 additions and 0 deletions
@ -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(sent) |
||||||
|
|
||||||
|
target_sources(app PRIVATE src/main.c) |
@ -0,0 +1,31 @@ |
|||||||
|
.. zephyr:code-sample:: sent |
||||||
|
:name: SENT interface |
||||||
|
:relevant-api: sent_interface |
||||||
|
|
||||||
|
Use the SENT (Single Edge Nibble Transmission) driver. |
||||||
|
|
||||||
|
Overview |
||||||
|
******** |
||||||
|
|
||||||
|
The sample application shows how to use the :ref:`SENT API <sent_api>`: |
||||||
|
|
||||||
|
* Receive data |
||||||
|
|
||||||
|
Requirements |
||||||
|
************ |
||||||
|
|
||||||
|
This sample requires a SENT sensor to be connected and exposed as ``sent0`` Devicetree alias. |
||||||
|
|
||||||
|
Building, Flashing and Running |
||||||
|
****************************** |
||||||
|
|
||||||
|
.. zephyr-app-commands:: |
||||||
|
:zephyr-app: samples/drivers/sent |
||||||
|
:board: s32z2xxdc2/s32z270/rtu0 |
||||||
|
:goals: build flash |
||||||
|
|
||||||
|
Sample Output: |
||||||
|
|
||||||
|
.. code-block:: console |
||||||
|
|
||||||
|
Received a frame on channel 1 |
@ -0,0 +1,38 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2025 NXP |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <dt-bindings/sent/sent.h> |
||||||
|
|
||||||
|
/ { |
||||||
|
aliases { |
||||||
|
sent0 = &sent1; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
&pinctrl { |
||||||
|
sent1_default: sent1_default { |
||||||
|
group1 { |
||||||
|
pinmux = <PK2_SENT_1_CH1_I>; |
||||||
|
input-enable; |
||||||
|
}; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
&sent1 { |
||||||
|
pinctrl-0 = <&sent1_default>; |
||||||
|
pinctrl-names = "default"; |
||||||
|
status = "okay"; |
||||||
|
}; |
||||||
|
|
||||||
|
&sent1_ch1 { |
||||||
|
num-data-nibbles = <6>; |
||||||
|
clock-tick-length-us = <3>; |
||||||
|
successive-calib-pulse-method = <2>; |
||||||
|
calib-pulse-tolerance-percent = <20>; |
||||||
|
fast-crc = <FAST_CRC_RECOMMENDED_IMPLEMENTATION>; |
||||||
|
short-serial-crc = <SHORT_CRC_RECOMMENDED_IMPLEMENTATION>; |
||||||
|
status = "okay"; |
||||||
|
}; |
@ -0,0 +1,7 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2025 NXP |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "s32z2xxdc2_s32z270_rtu0.overlay" |
@ -0,0 +1,3 @@ |
|||||||
|
CONFIG_SENT=y |
||||||
|
CONFIG_SENT_LOG_LEVEL_DBG=y |
||||||
|
CONFIG_LOG=y |
@ -0,0 +1,11 @@ |
|||||||
|
sample: |
||||||
|
name: SENT driver sample |
||||||
|
|
||||||
|
tests: |
||||||
|
sample.drivers.sent: |
||||||
|
tags: |
||||||
|
- drivers |
||||||
|
- sent |
||||||
|
depends_on: sent |
||||||
|
filter: dt_alias_exists("sent0") |
||||||
|
harness: sensor |
@ -0,0 +1,87 @@ |
|||||||
|
/*
|
||||||
|
* Copyright 2025 NXP |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <zephyr/logging/log.h> |
||||||
|
LOG_MODULE_REGISTER(sent_sample, LOG_LEVEL_DBG); |
||||||
|
|
||||||
|
#include <zephyr/kernel.h> |
||||||
|
|
||||||
|
#include <zephyr/drivers/sent/sent.h> |
||||||
|
|
||||||
|
#define SENT_NODE DT_ALIAS(sent0) |
||||||
|
#define SENT_CHANNEL 1 |
||||||
|
#define SENT_MAX_RX_BUFFER 1 |
||||||
|
|
||||||
|
struct sent_frame serial_frame[SENT_MAX_RX_BUFFER]; |
||||||
|
struct sent_frame fast_frame[SENT_MAX_RX_BUFFER]; |
||||||
|
|
||||||
|
void rx_serial_frame_cb(const struct device *dev, uint8_t channel_id, uint32_t num_frame, |
||||||
|
void *user_data) |
||||||
|
{ |
||||||
|
if (num_frame == SENT_MAX_RX_BUFFER) { |
||||||
|
LOG_INF("Received a frame on channel %d, " |
||||||
|
"id: %d, data: 0x%X, timestamp: 0x%X", |
||||||
|
channel_id, serial_frame->serial.id, serial_frame->serial.data, |
||||||
|
serial_frame->timestamp); |
||||||
|
} else { |
||||||
|
LOG_INF("Error received on channel %d", channel_id); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void rx_fast_frame_cb(const struct device *dev, uint8_t channel_id, uint32_t num_frame, |
||||||
|
void *user_data) |
||||||
|
{ |
||||||
|
if (num_frame == SENT_MAX_RX_BUFFER) { |
||||||
|
LOG_INF("Received a frame on channel %d, " |
||||||
|
"data nibble 0: 0x%X, " |
||||||
|
"data nibble 1: 0x%X, " |
||||||
|
"data nibble 2: 0x%X, " |
||||||
|
"data nibble 3: 0x%X, " |
||||||
|
"data nibble 4: 0x%X, " |
||||||
|
"data nibble 5: 0x%X, " |
||||||
|
"timestamp: 0x%X", |
||||||
|
channel_id, fast_frame->fast.data_nibbles[0], |
||||||
|
fast_frame->fast.data_nibbles[1], fast_frame->fast.data_nibbles[2], |
||||||
|
fast_frame->fast.data_nibbles[3], fast_frame->fast.data_nibbles[4], |
||||||
|
fast_frame->fast.data_nibbles[5], fast_frame->timestamp); |
||||||
|
} else { |
||||||
|
LOG_INF("Error received on channel %d", channel_id); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
struct sent_rx_callback_config serial_cb_cfg = { |
||||||
|
.callback = rx_serial_frame_cb, |
||||||
|
.frame = &serial_frame[0], |
||||||
|
.max_num_frame = SENT_MAX_RX_BUFFER, |
||||||
|
.user_data = NULL, |
||||||
|
}; |
||||||
|
|
||||||
|
struct sent_rx_callback_config fast_cb_cfg = { |
||||||
|
.callback = rx_fast_frame_cb, |
||||||
|
.frame = &fast_frame[0], |
||||||
|
.max_num_frame = SENT_MAX_RX_BUFFER, |
||||||
|
.user_data = NULL, |
||||||
|
}; |
||||||
|
|
||||||
|
struct sent_rx_callback_configs callback_configs = { |
||||||
|
.serial = &serial_cb_cfg, |
||||||
|
.fast = &fast_cb_cfg, |
||||||
|
}; |
||||||
|
|
||||||
|
int main(void) |
||||||
|
{ |
||||||
|
const struct device *const dev = DEVICE_DT_GET(SENT_NODE); |
||||||
|
|
||||||
|
sent_register_callback(dev, SENT_CHANNEL, callback_configs); |
||||||
|
|
||||||
|
sent_start_listening(dev, SENT_CHANNEL); |
||||||
|
|
||||||
|
while (true) { |
||||||
|
/* To receive data */ |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
# SPDX-License-Identifier: Apache-2.0 |
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.20.0) |
||||||
|
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) |
||||||
|
project(sent) |
||||||
|
|
||||||
|
FILE(GLOB app_sources src/*.c) |
||||||
|
target_sources(app PRIVATE ${app_sources}) |
@ -0,0 +1,38 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2025 NXP |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <dt-bindings/sent/sent.h> |
||||||
|
|
||||||
|
/ { |
||||||
|
aliases { |
||||||
|
sent0 = &sent1; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
&pinctrl { |
||||||
|
sent1_default: sent1_default { |
||||||
|
group1 { |
||||||
|
pinmux = <PK2_SENT_1_CH1_I>; |
||||||
|
input-enable; |
||||||
|
}; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
&sent1 { |
||||||
|
pinctrl-0 = <&sent1_default>; |
||||||
|
pinctrl-names = "default"; |
||||||
|
status = "okay"; |
||||||
|
}; |
||||||
|
|
||||||
|
&sent1_ch1 { |
||||||
|
num-data-nibbles = <6>; |
||||||
|
clock-tick-length-us = <3>; |
||||||
|
successive-calib-pulse-method = <2>; |
||||||
|
calib-pulse-tolerance-percent = <20>; |
||||||
|
fast-crc = <FAST_CRC_RECOMMENDED_IMPLEMENTATION>; |
||||||
|
short-serial-crc = <SHORT_CRC_RECOMMENDED_IMPLEMENTATION>; |
||||||
|
status = "okay"; |
||||||
|
}; |
@ -0,0 +1,7 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2025 NXP |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "s32z2xxdc2_s32z270_rtu0.overlay" |
@ -0,0 +1,2 @@ |
|||||||
|
CONFIG_ZTEST=y |
||||||
|
CONFIG_SENT=y |
@ -0,0 +1,123 @@ |
|||||||
|
/*
|
||||||
|
* Copyright 2025 NXP |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <zephyr/ztest.h> |
||||||
|
#include <zephyr/device.h> |
||||||
|
#include <zephyr/drivers/sent/sent.h> |
||||||
|
|
||||||
|
#define SENT_NODE DT_ALIAS(sent0) |
||||||
|
#define SENT_CHANNEL 1 |
||||||
|
#define SENT_MAX_RX_BUFFER 1 |
||||||
|
|
||||||
|
const struct device *sent_dev = DEVICE_DT_GET(SENT_NODE); |
||||||
|
|
||||||
|
struct sent_frame serial_frame[SENT_MAX_RX_BUFFER]; |
||||||
|
|
||||||
|
struct sent_frame fast_frame[SENT_MAX_RX_BUFFER]; |
||||||
|
|
||||||
|
static void *sent_setup(void) |
||||||
|
{ |
||||||
|
int err; |
||||||
|
|
||||||
|
zassert_true(device_is_ready(sent_dev), "SENT device is not ready"); |
||||||
|
|
||||||
|
err = sent_start_listening(sent_dev, SENT_CHANNEL); |
||||||
|
zassert_ok(err, "Failed to start rx (err %d)", err); |
||||||
|
|
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void rx_serial_frame_cb(const struct device *dev, uint8_t channel_id, uint32_t num_frame, |
||||||
|
void *user_data) |
||||||
|
{ |
||||||
|
ARG_UNUSED(dev); |
||||||
|
ARG_UNUSED(channel_id); |
||||||
|
ARG_UNUSED(num_frame); |
||||||
|
ARG_UNUSED(user_data); |
||||||
|
} |
||||||
|
|
||||||
|
void rx_fast_frame_cb(const struct device *dev, uint8_t channel_id, uint32_t num_frame, |
||||||
|
void *user_data) |
||||||
|
{ |
||||||
|
ARG_UNUSED(dev); |
||||||
|
ARG_UNUSED(channel_id); |
||||||
|
ARG_UNUSED(num_frame); |
||||||
|
ARG_UNUSED(user_data); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test starting rx is not allowed while started. |
||||||
|
*/ |
||||||
|
ZTEST_USER(sent_api, test_start_listening_while_started) |
||||||
|
{ |
||||||
|
int err; |
||||||
|
|
||||||
|
err = sent_start_listening(sent_dev, SENT_CHANNEL); |
||||||
|
zassert_not_ok(err, "Started rx while started"); |
||||||
|
zassert_equal(err, -EALREADY, "Wrong error return code (err %d)", err); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test stopping rx is not allowed while stopped. |
||||||
|
*/ |
||||||
|
ZTEST_USER(sent_api, test_stop_listening_while_stopped) |
||||||
|
{ |
||||||
|
int err; |
||||||
|
|
||||||
|
err = sent_stop_listening(sent_dev, SENT_CHANNEL); |
||||||
|
zassert_ok(err, "Failed to stop rx (err %d)", err); |
||||||
|
|
||||||
|
err = sent_stop_listening(sent_dev, SENT_CHANNEL); |
||||||
|
zassert_not_ok(err, "Stopped rx while stopped"); |
||||||
|
zassert_equal(err, -EALREADY, "Wrong error return code (err %d)", err); |
||||||
|
|
||||||
|
err = sent_start_listening(sent_dev, SENT_CHANNEL); |
||||||
|
zassert_ok(err, "Failed to start rx (err %d)", err); |
||||||
|
} |
||||||
|
|
||||||
|
struct sent_rx_callback_config serial_cb_cfg = { |
||||||
|
.callback = rx_serial_frame_cb, |
||||||
|
.frame = &serial_frame[0], |
||||||
|
.max_num_frame = SENT_MAX_RX_BUFFER, |
||||||
|
.user_data = NULL, |
||||||
|
}; |
||||||
|
|
||||||
|
struct sent_rx_callback_config fast_cb_cfg = { |
||||||
|
.callback = rx_fast_frame_cb, |
||||||
|
.frame = &fast_frame[0], |
||||||
|
.max_num_frame = SENT_MAX_RX_BUFFER, |
||||||
|
.user_data = NULL, |
||||||
|
}; |
||||||
|
|
||||||
|
struct sent_rx_callback_configs callback_configs = { |
||||||
|
.serial = &serial_cb_cfg, |
||||||
|
.fast = &fast_cb_cfg, |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test setting the rx callback. |
||||||
|
*/ |
||||||
|
ZTEST(sent_api, test_set_rx_callback) |
||||||
|
{ |
||||||
|
int err; |
||||||
|
|
||||||
|
err = sent_register_callback(sent_dev, SENT_CHANNEL, callback_configs); |
||||||
|
zassert_ok(err, "Failed to set rx callback (err %d)", err); |
||||||
|
|
||||||
|
callback_configs.serial = NULL; |
||||||
|
callback_configs.fast = NULL; |
||||||
|
|
||||||
|
err = sent_register_callback(sent_dev, SENT_CHANNEL, callback_configs); |
||||||
|
zassert_ok(err, "Failed to set rx callback (err %d)", err); |
||||||
|
|
||||||
|
callback_configs.serial = &serial_cb_cfg; |
||||||
|
callback_configs.fast = &fast_cb_cfg; |
||||||
|
|
||||||
|
err = sent_register_callback(sent_dev, SENT_CHANNEL, callback_configs); |
||||||
|
zassert_ok(err, "Failed to set rx callback (err %d)", err); |
||||||
|
} |
||||||
|
|
||||||
|
ZTEST_SUITE(sent_api, NULL, sent_setup, NULL, NULL, NULL); |
Loading…
Reference in new issue