openmv/lib/alif/se_services/source/services_host_clocks.c
iabdalkader daf2bb30da misc: Restructure repo.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2025-04-13 08:28:34 +02:00

490 lines
18 KiB
C
Executable File

/**
* @file services_host_clocks.c
*
* @brief Clocks services service source file
* @ingroup host_services
* @par
*
* Copyright (C) 2023 Alif Semiconductor - All Rights Reserved.
* Use, distribution and modification of this code is permitted under the
* terms stated in the Alif Semiconductor Software License Agreement
*
* You should have received a copy of the Alif Semiconductor Software
* License Agreement with this file. If not, please write to:
* contact@alifsemi.com, or visit: https://alifsemi.com/license
*
*/
/******************************************************************************
* I N C L U D E F I L E S
*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "services_lib_api.h"
#include "services_lib_protocol.h"
#include "services_lib_ids.h"
/**
* @fn uint32_t SERVICES_clocks_select_osc_source(uint32_t services_handle,
* oscillator_source_t source,
* oscillator_target_t target,
* uint32_t * error_code)
* @brief Select RC or XTAL as Oscillator clock source
* @param services_handle
* @param source RC or XTAL
* @param target SYSCLK (HF), PERIPHCLK (HF), S32K (LF)
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_clocks_select_osc_source(uint32_t services_handle,
oscillator_source_t source,
oscillator_target_t target,
uint32_t * error_code)
{
clk_select_clock_source_svc_t * p_svc =
(clk_select_clock_source_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(clk_select_clock_source_svc_t));
p_svc->send_clock_source = source;
p_svc->send_clock_target = target;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_CLOCK_SELECT_OSC_SOURCE, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_clocks_select_pll_source(uint32_t services_handle,
* oscillator_source_t source,
* oscillator_target_t target,
* uint32_t * error_code)
* @brief Select Oscillator or PLL clock source for various target clocks
* @param services_handle
* @param source Oscillator or PLL
* @param target SYSREFCLK, SYSCLK, ExtSus0, ExtSys1
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_clocks_select_pll_source(uint32_t services_handle,
pll_source_t source,
pll_target_t target,
uint32_t * error_code)
{
clk_select_clock_source_svc_t * p_svc =
(clk_select_clock_source_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(clk_select_clock_source_svc_t));
p_svc->send_clock_source = source;
p_svc->send_clock_target = target;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_CLOCK_SELECT_PLL_SOURCE, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_clocks_enable_clock(uint32_t services_handle,
* clock_enable_t clock,
* bool enable,
* uint32_t * error_code)
* @brief Select Oscialltor or PLL clock source for various target clocks
* @param services_handle
* @param clock Clock to enable or disable
* @param enable Enable/Disable flag
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_clocks_enable_clock(uint32_t services_handle,
clock_enable_t clock,
bool enable,
uint32_t * error_code)
{
clk_set_enable_svc_t * p_svc =
(clk_set_enable_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(clk_set_enable_svc_t));
p_svc->send_clock_type = clock;
p_svc->send_enable = enable;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_CLOCK_SET_ENABLE, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_clocks_set_ES0_frequency(uint32_t services_handle,
* clock_frequency_t frequency,
* uint32_t * error_code)
* @brief Set the clock frequency for External System 0 (M55-HP)
* @param services_handle
* @param frequency Clock frequency
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_clocks_set_ES0_frequency(uint32_t services_handle,
clock_frequency_t frequency,
uint32_t * error_code)
{
clk_m55_set_frequency_svc_t * p_svc =
(clk_m55_set_frequency_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(clk_m55_set_frequency_svc_t));
p_svc->send_frequency = frequency;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_CLOCK_ES0_SET_FREQ, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_clocks_set_ES1_frequency(uint32_t services_handle,
* clock_frequency_t frequency,
* uint32_t * error_code)
* @brief Set the clock frequency for External System 1 (M55-HE)
* @param services_handle
* @param frequency Clock frequency
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_clocks_set_ES1_frequency(uint32_t services_handle,
clock_frequency_t frequency,
uint32_t * error_code)
{
clk_m55_set_frequency_svc_t * p_svc =
(clk_m55_set_frequency_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(clk_m55_set_frequency_svc_t));
p_svc->send_frequency = frequency;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_CLOCK_ES1_SET_FREQ, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_clocks_select_a32_source(uint32_t services_handle,
* a32_source_t source,
* uint32_t * error_code)
* @brief Select a source clock for the A32 cores
* @param services_handle
* @param source Clock source
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_clocks_select_a32_source(uint32_t services_handle,
a32_source_t source,
uint32_t * error_code)
{
clk_select_sys_clk_source_svc_t * p_svc =
(clk_select_sys_clk_source_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(clk_select_sys_clk_source_svc_t));
p_svc->send_source = source;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_CLOCK_SELECT_A32_SOURCE, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_clocks_select_aclk_source(uint32_t services_handle,
* aclk_source_t source,
* uint32_t * error_code)
* @brief Select a source clock for system buses (AXI, AHB, APB)
* @param services_handle
* @param source Clock source
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_clocks_select_aclk_source(uint32_t services_handle,
aclk_source_t source,
uint32_t * error_code)
{
clk_select_sys_clk_source_svc_t * p_svc =
(clk_select_sys_clk_source_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(clk_select_sys_clk_source_svc_t));
p_svc->send_source = source;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_CLOCK_SELECT_ACLK_SOURCE, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_clocks_set_divider(uint32_t services_handle,
* clock_divider_t divider,
* uint32_t value,
* uint32_t * error_code)
* @brief Set the value of a divider
* @param services_handle
* @param divider Which divider
* @param value Divider value
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_clocks_set_divider(uint32_t services_handle,
clock_divider_t divider,
uint32_t value,
uint32_t * error_code)
{
clk_set_clk_divider_svc_t * p_svc =
(clk_set_clk_divider_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(clk_set_clk_divider_svc_t));
p_svc->send_divider = divider;
p_svc->send_value = value;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_CLOCK_SET_DIVIDER, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_pll_initialize(uint32_t services_handle,
* uint32_t * error_code)
* @brief High-level PLL initialize - startup HF XTAL and PLL, and switch to PLL
* @param services_handle
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_pll_initialize(uint32_t services_handle,
uint32_t * error_code)
{
generic_svc_t * p_svc =
(generic_svc_t *)SERVICES_prepare_packet_buffer(sizeof(generic_svc_t));
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_PLL_INITIALIZE, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_pll_deinit(uint32_t services_handle,
* uint32_t * error_code)
* @brief High-level PLL deinit - switch to RC clocks, stop PLL and HF XTAL
* @param services_handle
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_pll_deinit(uint32_t services_handle, uint32_t * error_code)
{
generic_svc_t * p_svc =
(generic_svc_t *)SERVICES_prepare_packet_buffer(sizeof(generic_svc_t));
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_PLL_DEINIT, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_pll_xtal_start(uint32_t services_handle,
* bool faststart,
* bool boost,
* uint32_t delay_count,
* uint32_t * error_code)
* @brief Start the HF XTAL
* @param services_handle
* @param faststart Enable faststart mode
* @param boost Enable boost mode
* @param delay_count Wait time
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_pll_xtal_start(uint32_t services_handle,
bool faststart,
bool boost,
uint32_t delay_count,
uint32_t * error_code)
{
pll_xtal_start_svc_t * p_svc = (pll_xtal_start_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(pll_xtal_start_svc_t));
p_svc->send_faststart = faststart;
p_svc->send_boost = boost;
p_svc->send_delay_count = delay_count;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_PLL_XTAL_START, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_pll_xtal_stop(uint32_t services_handle,
* uint32_t * error_code)
* @brief Stop the HF XTAL
* @param services_handle
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_pll_xtal_stop(uint32_t services_handle,
uint32_t * error_code)
{
generic_svc_t * p_svc =
(generic_svc_t *)SERVICES_prepare_packet_buffer(sizeof(generic_svc_t));
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_PLL_XTAL_STOP, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_pll_xtal_is_started(uint32_t services_handle,
* bool * is_started,
* uint32_t * error_code)
* @brief Check if the HF XTAL is started
* @param services_handle
* @param is_started
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_pll_xtal_is_started(uint32_t services_handle,
bool * is_started,
uint32_t * error_code)
{
generic_svc_t * p_svc =
(generic_svc_t *)SERVICES_prepare_packet_buffer(sizeof(generic_svc_t));
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_PLL_XTAL_IS_STARTED, DEFAULT_TIMEOUT);
*is_started = p_svc->resp_error_code != 0x0;
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_pll_clkpll_start(uint32_t services_handle,
* bool faststart,
* uint32_t delay_count,
* uint32_t * error_code)
* @brief Start the PLL
* @param services_handle
* @param faststart Enable faststart mode
* @param delay_count Wait time
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_pll_clkpll_start(uint32_t services_handle,
bool faststart,
uint32_t delay_count,
uint32_t * error_code)
{
pll_clkpll_start_svc_t * p_svc = (pll_clkpll_start_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(pll_clkpll_start_svc_t));
p_svc->send_faststart = faststart;
p_svc->send_delay_count = delay_count;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_PLL_CLKPLL_START, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_pll_clkpll_stop(uint32_t services_handle,
* uint32_t * error_code)
* @brief Stop the PLL
* @param services_handle
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_pll_clkpll_stop(uint32_t services_handle,
uint32_t * error_code)
{
generic_svc_t * p_svc =
(generic_svc_t *)SERVICES_prepare_packet_buffer(sizeof(generic_svc_t));
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_PLL_CLKPLL_STOP, DEFAULT_TIMEOUT);
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_pll_clkpll_is_locked(uint32_t services_handle,
* bool * is_locked,
* uint32_t * error_code)
* @brief Check if the PLL is started and locked
* @param services_handle
* @param is_locked Which divider
* @param error_code Service error code
* @return Transport layer error code
*/
uint32_t SERVICES_pll_clkpll_is_locked(uint32_t services_handle,
bool * is_locked,
uint32_t * error_code)
{
generic_svc_t * p_svc =
(generic_svc_t *)SERVICES_prepare_packet_buffer(sizeof(generic_svc_t));
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_PLL_CLKPLL_IS_LOCKED, DEFAULT_TIMEOUT);
*is_locked = p_svc->resp_error_code != 0x0;
*error_code = p_svc->resp_error_code;
return ret;
}
/**
* @fn uint32_t SERVICES_clocks_setting_get(uint32_t, clock_setting_t, uint32_t*, uint32_t*)
* @brief Get a clock setting from the 'clock_setting_t' enumeration
* @brief
* @param services_handle
* @param setting_type
* @param value
* @param error_code
* @return Transport layer error code
*/
uint32_t SERVICES_clocks_setting_get(uint32_t services_handle,
clock_setting_t setting_type,
uint32_t *value,
uint32_t *error_code)
{
clock_setting_svc_t * p_svc =
(clock_setting_svc_t *)
SERVICES_prepare_packet_buffer(sizeof(clock_setting_svc_t));
p_svc->send_setting_type = setting_type;
uint32_t ret = SERVICES_send_request(services_handle,
SERVICE_CLOCK_SETTING_GET_REQ_ID, DEFAULT_TIMEOUT);
if (SERVICES_REQ_SUCCESS == ret)
{
*value = p_svc->value;
}
*error_code = p_svc->resp_error_code;
return ret;
}