From 75a91dcfedc49ad72c9180d55873b683549eec9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pelikan?= Date: Wed, 20 Nov 2024 15:37:35 +0100 Subject: [PATCH] nrfs: add GDFS service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Pelikan --- nrfs/include/internal/nrfs_callbacks.h | 10 +++ nrfs/include/internal/nrfs_hdr.h | 2 +- .../internal/requests/nrfs_gdfs_reqs.h | 24 +++++ .../internal/requests/nrfs_reqs_common.h | 3 +- nrfs/include/internal/services/nrfs_gdfs.h | 46 ++++++++++ nrfs/include/services/nrfs_gdfs.h | 78 ++++++++++++++++ nrfs/src/internal/nrfs_dispatcher.c | 5 ++ nrfs/src/services/nrfs_gdfs.c | 89 +++++++++++++++++++ 8 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 nrfs/include/internal/requests/nrfs_gdfs_reqs.h create mode 100644 nrfs/include/internal/services/nrfs_gdfs.h create mode 100644 nrfs/include/services/nrfs_gdfs.h create mode 100644 nrfs/src/services/nrfs_gdfs.c diff --git a/nrfs/include/internal/nrfs_callbacks.h b/nrfs/include/internal/nrfs_callbacks.h index 746bca8c..2ce890c1 100644 --- a/nrfs/include/internal/nrfs_callbacks.h +++ b/nrfs/include/internal/nrfs_callbacks.h @@ -106,6 +106,16 @@ void nrfs_clock_service_notify(void *p_notification, size_t size); */ void nrfs_gdpwr_service_notify(void *p_notification, size_t size); +/** + * @brief Function for notifying the GDFS service about incoming message. + * + * This function is called internally by the dispatcher when the corresponding message arrives. + * + * @param[in] p_notification Pointer to the notification payload. + * @param[in] size Notification payload size. + */ +void nrfs_gdfs_service_notify(void *p_notification, size_t size); + #ifdef __cplusplus } #endif diff --git a/nrfs/include/internal/nrfs_hdr.h b/nrfs/include/internal/nrfs_hdr.h index 035ebef6..2f9af108 100644 --- a/nrfs/include/internal/nrfs_hdr.h +++ b/nrfs/include/internal/nrfs_hdr.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -19,7 +20,6 @@ #include #include - #ifdef __cplusplus extern "C" { #endif diff --git a/nrfs/include/internal/requests/nrfs_gdfs_reqs.h b/nrfs/include/internal/requests/nrfs_gdfs_reqs.h new file mode 100644 index 00000000..6cfdb2c8 --- /dev/null +++ b/nrfs/include/internal/requests/nrfs_gdfs_reqs.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFS_GDFS_REQS_H +#define NRFS_GDFS_REQS_H + +#include "nrfs_reqs_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NRFS_GDFS_REQ_FREQ = NRFS_REQUEST_ID_DEF(NRFS_SERVICE_ID_GDFS, 0x01), +}; + +#ifdef __cplusplus +} +#endif + +#endif /* NRFS_GDFS_REQS_H */ diff --git a/nrfs/include/internal/requests/nrfs_reqs_common.h b/nrfs/include/internal/requests/nrfs_reqs_common.h index 6f3edf2b..2d79d3c2 100644 --- a/nrfs/include/internal/requests/nrfs_reqs_common.h +++ b/nrfs/include/internal/requests/nrfs_reqs_common.h @@ -61,7 +61,8 @@ enum { NRFS_SERVICE_ID_PMIC, NRFS_SERVICE_ID_RESET, NRFS_SERVICE_ID_TEMP, - NRFS_SERVICE_ID_USB + NRFS_SERVICE_ID_USB, + NRFS_SERVICE_ID_GDFS }; #ifdef __cplusplus diff --git a/nrfs/include/internal/services/nrfs_gdfs.h b/nrfs/include/internal/services/nrfs_gdfs.h new file mode 100644 index 00000000..72b65ef0 --- /dev/null +++ b/nrfs/include/internal/services/nrfs_gdfs.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFS_INTERNAL_GDFS_H +#define NRFS_INTERNAL_GDFS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum __NRFS_PACKED gdfs_frequency_setting { + GDFS_FREQ_HIGH = 0, + GDFS_FREQ_MEDHIGH = 1, + GDFS_FREQ_MEDLOW = 2, + GDFS_FREQ_LOW = 3, + GDFS_FREQ_COUNT +}; + +/** @brief Global Domain Frequency Scaling service request data structure. */ +typedef struct __NRFS_PACKED { + enum gdfs_frequency_setting target_freq; /** Requested frequency oppoint. */ +} nrfs_gdfs_req_data_t; + +/** @brief Global Domain Frequency Scaling frequency change request structure. */ +typedef struct __NRFS_PACKED { + nrfs_hdr_t hdr; /**< Header of the message. */ + nrfs_ctx_t ctx; /**< Context of the message. */ + nrfs_gdfs_req_data_t data; /**< Data of the request. */ +} nrfs_gdfs_req_t; + +/** @brief Global Domain Frequency Scaling service notification structure. */ +typedef struct __NRFS_PACKED { + nrfs_hdr_t hdr; /**< Header of the message. */ + nrfs_ctx_t ctx; /**< Context of the message. */ +} nrfs_gdfs_rsp_t; + +#ifdef __cplusplus +} +#endif + +#endif /* NRFS_INTERNAL_GDFS_H */ diff --git a/nrfs/include/services/nrfs_gdfs.h b/nrfs/include/services/nrfs_gdfs.h new file mode 100644 index 00000000..ed6cd2b3 --- /dev/null +++ b/nrfs/include/services/nrfs_gdfs.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFS_GDFS_H +#define NRFS_GDFS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Global Domain Frequency Scaling service event types. */ +typedef enum __NRFS_PACKED { + NRFS_GDFS_EVT_REJECT, /** General purpose event for rejected requests. */ + NRFS_GDFS_EVT_FREQ_CONFIRMED, /** Frequency has been acheived. */ +} nrfs_gdfs_evt_type_t; + +/** @brief Global Domain Frequency Scaling service event. */ +typedef struct { + nrfs_gdfs_evt_type_t type; /** Event type. */ +} nrfs_gdfs_evt_t; + +/** @brief Global Domain Frequency Scaling service event handler type. */ +typedef void (*nrfs_gdfs_evt_handler_t)(nrfs_gdfs_evt_t const * p_evt, void * context); + +/** + * @brief Function for initializing the Global Domain Frequency Scaling service. + * + * @param[in] handler Function called as a response to the request. + * + * @retval NRFS_SUCCESS Service initialized successfully. + * @retval NRFS_ERR_INVALID_STATE Service was already initialized. + */ +nrfs_err_t nrfs_gdfs_init(nrfs_gdfs_evt_handler_t handler); + +/** + * @brief Function for uninitializing the Global Domain Frequency Scaling service. + * + * @warning Notifications from previous requests are dropped after service uninitialization. + */ +void nrfs_gdfs_uninit(void); + +/** + * @brief Function for requesting a frequency change. + * @note The @p target_freq requirement might not be met by the system + * until the NRFS_GDFS_EVT_FREQ_CONFIRMED response is triggered. + * + * @param[in] target_freq Minimal required frequency + * @param[in] p_context Opaque user data that will be passed to registered callback. + * + * @retval NRFS_SUCCESS Request sent successfully. + * @retval NRFS_ERR_INVALID_STATE Service is uninitialized. + * @retval NRFS_ERR_IPC Backend returned error during request sending. + */ +nrfs_err_t nrfs_gdfs_request_freq(enum gdfs_frequency_setting target_freq, void * p_context); + +/** + * @brief Function for requesting a frequency change. + * @note The response @p NRFS_GDFS_EVT_FREQ_CONFIRMED will not be triggered. + * + * @param[in] target_freq Minimal required frequency + * @param[in] p_context Opaque user data that will be passed to registered callback. + * + * @retval NRFS_SUCCESS Request sent successfully. + * @retval NRFS_ERR_INVALID_STATE Service is uninitialized. + * @retval NRFS_ERR_IPC Backend returned error during request sending. + */ +nrfs_err_t nrfs_gdfs_request_freq_no_rsp(enum gdfs_frequency_setting target_freq, void * p_context); + +#ifdef __cplusplus +} +#endif + +#endif /* NRFS_GDFS_H */ diff --git a/nrfs/src/internal/nrfs_dispatcher.c b/nrfs/src/internal/nrfs_dispatcher.c index 34e1cbdd..ac2ebe2c 100644 --- a/nrfs/src/internal/nrfs_dispatcher.c +++ b/nrfs/src/internal/nrfs_dispatcher.c @@ -55,6 +55,11 @@ static const nrfs_service_cb_t services_callbacks[] = { #else [NRFS_SERVICE_ID_GDPWR] = NULL, #endif +#ifdef NRFS_GDFS_SERVICE_ENABLED + [NRFS_SERVICE_ID_GDFS] = nrfs_gdfs_service_notify, +#else + [NRFS_SERVICE_ID_GDFS] = NULL, +#endif }; /* Warning! All "UNSOLICITED" features are not supported. This is intended for possible future use. */ diff --git a/nrfs/src/services/nrfs_gdfs.c b/nrfs/src/services/nrfs_gdfs.c new file mode 100644 index 00000000..7932e780 --- /dev/null +++ b/nrfs/src/services/nrfs_gdfs.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +typedef struct { + nrfs_gdfs_evt_handler_t handler; + bool is_initialized; +} nrfs_gdfs_cb_t; +static nrfs_gdfs_cb_t m_cb; + +void nrfs_gdfs_service_notify(void *p_notification, size_t size) +{ + if (!m_cb.handler || !m_cb.is_initialized) { + return; + } + + nrfs_gdfs_evt_t evt; + nrfs_generic_t *p_data = (nrfs_generic_t *)p_notification; + if (NRFS_HDR_FILTER_ERR_GET(&p_data->hdr)) { + evt.type = NRFS_GDFS_EVT_REJECT; + m_cb.handler(&evt, (void *)p_data->ctx.ctx); + return; + } + + nrfs_gdfs_rsp_t *p_rsp = (nrfs_gdfs_rsp_t *)p_notification; + switch (p_data->hdr.req) { + case NRFS_GDFS_REQ_FREQ: + evt.type = NRFS_GDFS_EVT_FREQ_CONFIRMED; + m_cb.handler(&evt, (void *)p_rsp->ctx.ctx); + break; + + default: + break; + } +} + +nrfs_err_t nrfs_gdfs_init(nrfs_gdfs_evt_handler_t handler) +{ + if (m_cb.is_initialized) { + return NRFS_ERR_INVALID_STATE; + } + + m_cb.handler = handler; + m_cb.is_initialized = true; + return NRFS_SUCCESS; +} + +void nrfs_gdfs_uninit(void) +{ + m_cb.is_initialized = false; +} + +nrfs_err_t nrfs_gdfs_request_freq(enum gdfs_frequency_setting target_freq, void *p_context) +{ + if (!m_cb.is_initialized) { + return NRFS_ERR_INVALID_STATE; + } + + nrfs_gdfs_req_t req; + + NRFS_SERVICE_HDR_FILL(&req, NRFS_GDFS_REQ_FREQ); + req.ctx.ctx = (uint32_t)p_context; + req.data.target_freq = target_freq; + + return nrfs_backend_send(&req, sizeof(req)); +} + +nrfs_err_t nrfs_gdfs_request_freq_no_rsp(enum gdfs_frequency_setting target_freq, + void *p_context) +{ + if (!m_cb.is_initialized) { + return NRFS_ERR_INVALID_STATE; + } + + nrfs_gdfs_req_t req; + + NRFS_SERVICE_HDR_FILL(&req, NRFS_GDFS_REQ_FREQ); + NRFS_HDR_NO_RSP_SET(&req.hdr); + req.ctx.ctx = (uint32_t)p_context; + req.data.target_freq = target_freq; + + return nrfs_backend_send(&req, sizeof(req)); +}