Skip to content

Commit

Permalink
nrfs: add GDFS service
Browse files Browse the repository at this point in the history
Signed-off-by: Paweł Pelikan <pawel.pelikan@nordicsemi.no>
  • Loading branch information
ppelikan-nordic authored and rlubos committed Dec 12, 2024
1 parent 8097b08 commit fae1542
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 2 deletions.
10 changes: 10 additions & 0 deletions nrfs/include/internal/nrfs_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion nrfs/include/internal/nrfs_hdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
#include <internal/requests/nrfs_clock_reqs.h>
#include <internal/requests/nrfs_diag_reqs.h>
#include <internal/requests/nrfs_dvfs_reqs.h>
#include <internal/requests/nrfs_gdfs_reqs.h>
#include <internal/requests/nrfs_gdpwr_reqs.h>
#include <internal/requests/nrfs_mram_reqs.h>
#include <internal/requests/nrfs_pmic_reqs.h>
#include <internal/requests/nrfs_reset_reqs.h>
#include <internal/requests/nrfs_temp_reqs.h>
#include <internal/requests/nrfs_usb_reqs.h>


#ifdef __cplusplus
extern "C" {
#endif
Expand Down
24 changes: 24 additions & 0 deletions nrfs/include/internal/requests/nrfs_gdfs_reqs.h
Original file line number Diff line number Diff line change
@@ -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 */
3 changes: 2 additions & 1 deletion nrfs/include/internal/requests/nrfs_reqs_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
46 changes: 46 additions & 0 deletions nrfs/include/internal/services/nrfs_gdfs.h
Original file line number Diff line number Diff line change
@@ -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 <internal/services/nrfs_generic.h>

#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 */
78 changes: 78 additions & 0 deletions nrfs/include/services/nrfs_gdfs.h
Original file line number Diff line number Diff line change
@@ -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 <internal/services/nrfs_gdfs.h>

#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 */
5 changes: 5 additions & 0 deletions nrfs/src/internal/nrfs_dispatcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
89 changes: 89 additions & 0 deletions nrfs/src/services/nrfs_gdfs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <internal/nrfs_backend.h>
#include <internal/nrfs_callbacks.h>
#include <nrfs_gdfs.h>

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));
}

0 comments on commit fae1542

Please sign in to comment.